TIL

[250402 TIL] JWT 인증 로그아웃 구현(Redis 활용)

도원좀비 2025. 4. 2. 20:11

1️⃣ 오늘의 작업 흐름

 

  1. Redis 설치/연동
    • 로컬 환경에 Docker로 Redis 설치
    • docker run -d --name redis -p 6379:6379 redis
    • application.properties 설정
    • spring.redis.host=localhost
      spring.redis.port=6379
  2. Refresh Token 저장 구조 설계
    • 로그인 시 "RT:{authorId}" 키로 Redis에 저장
    • 만료 시간은 7일 기준 (TimeUnit.DAYS)
  3. 로그아웃 처리
    • 클라이언트에서 /login/logout 요청 시
    • Authorization 헤더에서 Refresh Token 추출
    • Redis에서 "RT:{authorId}" 키 삭제
  4. 재발급 보안 강화
    • /login/reissue 호출 시 Redis에 저장된 토큰과 비교
    • 다를 경우 TOKEN_INVALID 예외 발생
  5. 예외 처리 구조 확립
    • 필터 단계는 직접 JSON 응답 반환
    • 컨트롤러/서비스 단계는 GlobalExceptionHandler에서 통일

2️⃣ 오늘의 핵심 코드

로그인 시 토큰 저장

redisTemplate.opsForValue().set(
    "RT:" + author.getAuthorId(),
    refreshToken,
    7, TimeUnit.DAYS
);

 

 

로그아웃

@Override
public void logout(String refreshToken) {
    String authorId = jwtTokenProvider.getAuthorId(refreshToken);
    redisTemplate.delete("RT:" + authorId);
}

 

재발급 시 검증

String stored = redisTemplate.opsForValue().get("RT:" + authorId);
if (stored == null || !stored.equals(refreshToken)) {
    throw new CustomException(ExceptionCode.TOKEN_INVALID);
}

3️⃣ 배운 점

 

  • Redis를 활용한 JWT 로그아웃 처리 방식은 Refresh Token 무효화에 적합
  • 필터에서는 @ControllerAdvice 예외가 적용되지 않으므로, 직접 JSON 에러 응답 구성 필요
  • 토큰 관련 모든 흐름을 하나의 흐름으로 통합 정리할 수 있다