JWT는 서버에 인증 상태를 저장하지 않기 때문에 "로그아웃" 기능을 직접 구현해줘야 한다. 이를 해결하기 위해 Redis에 블랙리스트(Blacklist) 방식을 사용했다.
✅ 로그아웃 설계 개요
- AccessToken을 클라이언트에서 받아와 유효성 확인
- RefreshToken 삭제
- AccessToken을 Redis에 블랙리스트로 저장
- 블랙리스트의 TTL(Time To Live)은 AccessToken의 남은 유효시간
✅ 로그아웃 구현 코드
📌 UserService.java
public void logout(String requestHeader) {
if (requestHeader == null || !requestHeader.startsWith("Bearer ")) {
throw new BadCredentialsException("AccessToken이 존재하지 않거나 형식이 잘못되었습니다.");
}
String accessToken = requestHeader.substring(7);
String userId;
try {
userId = jwtUtil.getUsernameFromToken(accessToken);
} catch (Exception e) {
throw new BadCredentialsException("AccessToken이 유효하지 않거나 만료되었습니다.");
}
// RefreshToken 삭제
stringRedisTemplate.delete("RT:" + userId);
// AccessToken 블랙리스트 등록 (남은 유효 시간만큼)
long remainTime = jwtUtil.getExpirationTime(accessToken);
stringRedisTemplate.opsForValue().set("BL:" + accessToken, "logout", remainTime, TimeUnit.MILLISECONDS);
}
📌 JwtAuthenticationFilter.java
if (stringRedisTemplate.hasKey("BL:" + token)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("로그아웃된 토큰입니다.");
return;
}
✅ 블랙리스트가 필요한 이유
- JWT는 stateless 하기 때문에 토큰을 폐기할 수 없다.
- 로그아웃 시 서버에서 JWT를 저장소에 등록해 "이 토큰은 사용하면 안된다"는 정보를 저장한다.
- 인증 필터에서 이를 검증하여 로그아웃된 토큰으로의 접근을 차단할 수 있다.
'BackEnd > JWT' 카테고리의 다른 글
Spring Boot CORS 설정 정리 (0) | 2025.05.07 |
---|---|
JWT Refresh Token을 이용한 Access Token 재발급 구현 (Spring Boot) (0) | 2025.05.06 |
Spring Security – JWT 인증 필터 & SecurityConfig 리팩토링 (0) | 2025.05.01 |
Spring Security - JWT 인증 필터 구현기 (JwtAuthenticationFilter) (0) | 2025.04.30 |
Spring Boot 로그인 API & JWT 발급 구현 (0) | 2025.04.30 |