2024년 4월기준 아래처럼 바뀌었습니다. 내용 공유드립니다.

public class JwtUtils {
    private static final String SECRET_KEY = "4261656C64756E67";

    private SecretKey getSigningKey() {
        byte[] keyBytes = Decoders.BASE64.decode(this.SECRET_KEY);
        return Keys.hmacShaKeyFor(keyBytes);
    }

    // JWT 생성
    public String generateToken(Authentication authentication) {
        // 인증 정보에서 사용자 이름 추출
        String username = ((UserDetails) authentication.getPrincipal()).getUsername();

        return Jwts.builder()
                .subject(username)
                .issuedAt(new Date())
                .expiration(new Date((new Date()).getTime() + 3600000))
                .signWith(this.getSigningKey())
                .compact();
    }

    private Claims extractAllClaims(String token){
        return Jwts.parser()
                .verifyWith(this.getSigningKey())
                .build()
                .parseSignedClaims(token)
                .getPayload();
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

---------------------------------------------------

문제상황->

public String create(UserEntity userEntity) {
        // 기한 지금으로부터 1일로 설정
        Date expiryDate = Date.from(
                Instant.now()
                        .plus(1, ChronoUnit.DAYS));
	
        // JWT Token 생성
        return Jwts.builder()
                // header에 들어갈 내용 및 서명을 하기 위한 SECRET_KEY
                // payload에 들어갈 내용
                .signWith(SignatureAlgorithm.HS512, "abcde")
                .setSubject(userEntity.getId()) // sub
                .setIssuer("demo app") // iss
                .setIssuedAt(new Date()) // iat
                .setExpiration(expiryDate) // exp
                .compact();
    }

문자열 혹은 바이트를 인수로 받는 signWith 메서드가
Deprecated 되었습니다.
signWith 메서드는 지정된 키와 지정된 알고리즘을 사용해
토큰에 서명을합니다.
하지만 위 코드처럼 특정 문자열이나 byte를 인수로 받는 메서드는 사용중단되었다고 합니다.
이유는 많은 사용자가 원시적인 암호 문자열(안전하지 않은)을
키 인수로 사용하려고 시도하며 혼란스러워 했기 때문이랍니다.

해결방법->

 private Key key = Keys.secretKeyFor(SignatureAlgorithm.HS512);
 
 return Jwts.builder()
                // header에 들어갈 내용 및 서명을 하기 위한 SECRET_KEY
                // payload에 들어갈 내용
                .signWith(key)
                .setSubject(userEntity.getId()) // sub
                .setIssuer("demo app") // iss
                .setIssuedAt(new Date()) // iat
                .setExpiration(expiryDate) // exp
                .compact();

java.security의 Key 객체를 인수로 넣습니다.
Key객체를 생성할때 알고리즘을 적용할 수도 있고,
signWith 메서드의 2번째 인수로 알고리즘을 넣어도 됩니다.


저는 로그인 시 JWT가 생성되게 세팅해놓았는데
Postman으로 테스트 결과 잘 작동하는 모습입니다.

덧붙여,

        Claims claims = Jwts.parser()
                .setSigningKey("abcd")
                .parseClaimsJws(token)
                .getBody();
                
                ->
                
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(token)
                .getBody();         

위 상황으로 말미암아 문자열 구문 분석에 쓰이는 Jwts의 parser메서드도 deprecated 되었으니
parserBuilder메서드를 사용해 주시면 되겠습니다!

+ Recent posts