JWT 토큰 발급 후 만료되는 문제
로그인 후 JWT 토큰을 발급 받아 쿠키에 저장하고 이를 @CookieValue 를 통해 사용하는 로직을 구현 하였다.
토큰 발급 시간을 24시간으로 설정하였지만 1분이 조금 지나면 계속해서 토큰이 만료 되었다.
error message :
There was an unexpected error (type=Internal Server Error, status=500).
JWT expired 106942 milliseconds ago at 2024-12-13T03:22:16.000Z. Current time: 2024-12-13T03:24:02.942Z. Allowed clock skew: 0 milliseconds.
io.jsonwebtoken.ExpiredJwtException: JWT expired 106942 milliseconds ago at 2024-12-13T03:22:16.000Z. Current time: 2024-12-13T03:24:02.942Z. Allowed clock skew: 0 milliseconds.
(토큰을 발급된 시간과 만료 시간이 1분으로 설정되어 있다)
jwtToken 을 발급받는 createJwt 메서드와 createJwt 메서드를 사용하여 실제 토큰을 받는 코드를 다시 확인 하였다.
원인 : 로그인 필터와 jwtUtil 객체 간의 expired(만료 시간) 단위 설정 오류
String token = jwtUtil.createJwt(empUUID, roleType,60 * 60 * 24L);
현재 로그인 필터 객체 내에서 최종 토큰을 발급 받기 위해 createJwt 메서드의 파라미터 인자로 들어가는 시점에는 expired 를 설정 시간이 60 * 60 * 24L 를 초단위로 계산한 데이터를 넣기 위한 의도 때문에 24시간의 토큰 유지 시간을 설정 하고 있는 것으로 보이지만 실제 데이터가 JwtUtil 객체 내의 createJwt 메서드에 적용 시, ms 로 환산한 값이 되기 때문에 86초로 계산되어 1분 후에 토큰이 만료 되는 것이었다.
public String createJwt(String empUUID, String roleType, Long expired) {
return Jwts.builder()
.claim("empUUID", empUUID)
.claim("roleType", roleType)
.issuedAt(new Date(System.currentTimeMillis()))
.expiration(new Date(System.currentTimeMillis() + expired))
.signWith(secretKey)
.compact();
}
String token = jwtUtil.createJwt(empUUID, roleType,60 * 60 * 24 * 1000L);
해결 방법 : 로그인 필터 expired 시간 설정 값을 60 * 60 * 24 * 1000L (86,400,000)초 설정하여 JwtUtil 객체의 createJwt 메서드 내부 파라미터로 환산 될 때 밀리초로 변환되었을 때도, 24시간을 유지 할 수 있도록 하였다
(86,400,000 ms = 24 hours)
JWT 토큰의 만료시간을 밀리초 단위로 설정하는 이유
1. 정밀한 만료 시간 처리
- 밀리초 단위로 시간을 설정하는 것이 더 정확하고 세밀한 제어를 제공할 수 있다
2. JWT 표준화
- JWT 스펙에서는 expired 클레임을 Date 객체로 처리 한다. (Date = 밀리초 단위로 시간을 저장)
3. 데이터베이스와의 호환성
- 많은 시스템(데이터베이스, 애플리케이션 서버 등)에서는 시간을 밀리초 단위로 처리하기 때문에 클라이언트 간의 시간도 밀리초 단위로 설정하여 일관성을 유지 하는 것이 좋다.