JWT Token io.jsonwebtoken.ExpiredJwtException: JWT expired

Discussão em 'Angular' iniciado por Ramzi Hadjsalem, Novembro 9, 2024.

  1. I have a Spring Boot (with Angular) application. My application works fine locally, but when I Dockerize my application an error throws when I have to register new user:token expired.

    The question which supposes why when I launch in my IDE it works well and no problem is displayed.

    application.yml:

    spring:
    datasource:
    url: ${SPRING_DATASOURCE_URL}
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver
    jpa:
    hibernate:
    ddl-auto: update
    show-sql: true
    properties:
    hibernate:
    dialect: org.hibernate.dialect.MySQLDialect

    server:
    port: 8083

    application:
    security:
    jwt:
    secret-key: ${JWT_SECRET_KEY}
    expiration: 86400000000000000000
    refresh-token:
    expiration: 86400000000000000000

    mail:
    host: smtp.gmail.com
    port: 587
    username: ${MAIL_USERNAME}
    password: ${MAIL_PASSWORD}
    properties:
    mail:
    smtp:
    auth: true
    starttls.enable: true



    docker-compose.yml:

    version: '3.8'
    services:
    backend:
    image: communicationbackend
    ports:
    - "8083:8083"
    environment:
    SPRING_DATASOURCE_URL: ${SPRING_DATASOURCE_URL}
    SPRING_DATASOURCE_USERNAME: ${DB_USERNAME} # Correct variable name
    SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD} # Correct variable name
    JWT_SECRET_KEY: ${JWT_SECRET_KEY}
    MAIL_USERNAME: ${MAIL_USERNAME}
    MAIL_PASSWORD: ${MAIL_PASSWORD}
    depends_on:
    - db
    networks:
    - app-network
    env_file:
    - .env # Charge les variables d'environnement

    frontend:
    image: ramzi/frontend
    ports:
    - "82:80"
    networks:
    - app-network

    db:
    image: mysql:5.7
    environment:
    MYSQL_DATABASE: db-communication
    MYSQL_ROOT_PASSWORD: root
    MYSQL_USER: ${DB_USERNAME}
    MYSQL_PASSWORD: ${DB_PASSWORD}
    ports:
    - "3307:3306"
    volumes:
    - db_data:/var/lib/mysql
    networks:
    - app-network
    env_file:
    - .env

    volumes:
    db_data:

    networks:
    app-network:


    application.yml:

    spring:
    datasource:
    url: ${SPRING_DATASOURCE_URL}
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver
    jpa:
    hibernate:
    ddl-auto: update
    show-sql: true
    properties:
    hibernate:
    dialect: org.hibernate.dialect.MySQLDialect

    server:
    port: 8083

    application:
    security:
    jwt:
    secret-key: ${JWT_SECRET_KEY}
    expiration: 8640000000
    refresh-token:
    expiration: 864000000

    mail:
    host: smtp.gmail.com
    port: 587
    username: ${MAIL_USERNAME}
    password: ${MAIL_PASSWORD}
    properties:
    mail:
    smtp:
    auth: true
    starttls.enable: true


    .env:

    # Variables de la base de données
    DB_USERNAME=communication
    DB_PASSWORD=password
    SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/db-communication

    # JWT secret
    JWT_SECRET_KEY=IS/A4dZ9K2z5tQSV3eGK2i4RGNdiD7qbGGTNq9xUZqO4pqa8+BIan+scnhFPz15pSFWkTGve4YNxWHXt90U5Tg==

    # Configurations de l'email
    MAIL_USERNAME=****************
    MAIL_PASSWORD=***************


    I launch my Docker containers, it works. I access my frontend, it is open when I have to register:

    Failed to load resource: the server responded with a status of 403 ()
    :8083/PlatformCommunication/v1/register:1
    Failed to load resource: the server responded with a status of 403 ()


    So please, how to fix that?

    jwtservice:

    @Service
    public class JwtService {

    @Value("${application.security.jwt.secret-key}")
    private String secretKey; // Injecting the secret key from application.yml

    @Value("${application.security.jwt.expiration}")
    private long jwtExpiration;

    @Value("${application.security.jwt.refresh-token.expiration}")
    private long refreshExpiration;

    public String extractUsername(String token) {
    return extractClaim(token, Claims::getSubject);
    }

    public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
    final Claims claims = extractAllClaims(token);
    return claimsResolver.apply(claims);
    }

    public String generateToken(UserDetails userDetails) {
    return generateToken(new HashMap<>(), userDetails);
    }

    public String generateToken(
    Map<String, Object> extraClaims,
    UserDetails userDetails
    ) {
    return buildToken(extraClaims, userDetails, jwtExpiration);
    }

    public String generateRefreshToken(
    UserDetails userDetails
    ) {
    return buildToken(new HashMap<>(), userDetails, refreshExpiration);
    }

    private String buildToken(
    Map<String, Object> extraClaims,
    UserDetails userDetails,
    long expiration
    ) {
    return Jwts
    .builder()
    .setClaims(extraClaims)
    .setSubject(userDetails.getUsername())
    .setIssuedAt(new Date(System.currentTimeMillis()))
    .setExpiration(new Date(System.currentTimeMillis() + expiration))
    .signWith(getSignInKey(), SignatureAlgorithm.HS256)
    .compact();
    }

    public boolean isTokenValid(String token, UserDetails userDetails) {
    final String username = extractUsername(token);
    return (username.equals(userDetails.getUsername())) && !isTokenExpired(token);
    }

    public boolean isTokenExpired(String token) {
    return extractExpiration(token).before(new Date());
    }

    public Date extractExpiration(String token) {
    return extractClaim(token, Claims::getExpiration);
    }

    private Claims extractAllClaims(String token) {
    return Jwts
    .parserBuilder()
    .setSigningKey(getSignInKey())
    .build()
    .parseClaimsJws(token)
    .getBody();
    }

    private Key getSignInKey() {
    byte[] keyBytes = Decoders.BASE64.decode(secretKey);
    return Keys.hmacShaKeyFor(keyBytes);
    }
    }

    Continue reading...

Compartilhe esta Página