Refresh Token을 이용한 Access Token 재발급 로직
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
// 생략
String token = jwtUtil.substringToken(authorization);
log.info("authorization = {}", authorization);
try {
jwtUtil.validateToken(token);
return chain.filter(exchange);
} catch (SecurityException | MalformedJwtException | SignatureException e) {
return onError(exchange, "유효하지 않는 JWT 서명 입니다.", HttpStatus.UNAUTHORIZED);
} catch (ExpiredJwtException e) {
log.info("Access Token 만료");
Claims claims = e.getClaims();
log.info("Redis에 저장된 RefreshToken 추출");
String refreshToken = redisService.getRefreshToken(claims.getSubject());
if(refreshToken != null && jwtUtil.validateToken(refreshToken)){
log.info("유효한 Refresh Token으로 Access Token 재발급");
String newAccessToken = jwtUtil.createAccessToken(claims);
jwtUtil.addJwtToHeader(newAccessToken, exchange.getResponse());
return chain.filter(exchange);
} else{
log.info("유효하지 않은 Refresh Token(기간 만료 or Refresh Token 존재하지 않음)");
return onError(exchange, "로그인 후 이용 가능합니다.", HttpStatus.UNAUTHORIZED);
}
} catch (UnsupportedJwtException e) {
return onError(exchange, "지원되지 않는 JWT 토큰 입니다.", HttpStatus.UNAUTHORIZED);
} catch (IllegalArgumentException e) {
return onError(exchange, "잘못된 JWT 토큰 입니다.", HttpStatus.UNAUTHORIZED);
}
});
}
- jwtUtil.validateToken() 메서드를 사용하여 토큰 검증
- Access Token이 만료되었을 경우 catch (ExpiredJwtException e){} 예외 처리 실행
- ExpriedJwtException에는 만료된 토큰의 claims에 접근 가능
- Redis에 저장한 키 값으로 Refresh Token 추출
- Refresh Token이 null이 아니고(Redis에 저장) 유효한 토큰일 경우 새로운 Access Token 발급하여 Response Header에 추가
- 다음 필터로 진행
- Redis에 Refresh Token이 없거나 만료된 토큰일 경우 Error 메세지 및 상태 응답
Postman을 이용한 테스트
시나리오
- Access Token 만료 시간 : 25초
- Refresh Token 만료 시간 : 60초
jwt:
token:
access-expiration : 250000 # 25초
refresh-expiration : 60000 # 1분
- 기존 액세스 토큰으로 게임 전체 리스트 조회 → 실패 : 로그인 후 사용 가능
- 로그인 → 성공
- 게임리스트 조회 → 성공
- 25초 뒤 게임리스트 조회 → 성공 : Access Token 재발급
- 35초 뒤 다시 로그인(1분) → 실패 : 로그인 후 사용 가능
기존 액세스 토큰으로 게임 전체 리스트 조회 → 실패 : 로그인 후 사용 가능
로그인 → 성공
게임리스트 조회 → 성공
25초 뒤 게임리스트 조회 → 성공 : Access Token 재발급
35초 뒤 다시 로그인(1분) → 실패 : 로그인 후 사용 가능
'Language > Spring' 카테고리의 다른 글
[JPA] JPA의 개념 / JPA를 사용해야하는 상황과 그렇지 못한 상황 (1) | 2024.11.08 |
---|---|
[Redis] 캐시란? (0) | 2024.09.07 |
[JWT] JwtUtil 사용 예제 및 설명 (0) | 2024.08.27 |
[JWT] JWT 등장 배경, Access Token, Refresh Token (0) | 2024.08.27 |
[Authentication] Cookie, Session, JWT Token (0) | 2024.08.26 |