Spring Security에서 SessionCreationPolicy.STATELESS를 설정하고 JWT를 사용하면 stateless 인증을 구현한 것처럼 보인다. 하지만 현재 코드를 기준으로 분석하면 완전한 stateless 구조는 아니다.
Stateless한 부분
SessionCreationPolicy.STATELESS 설정으로 HTTP 세션을 사용하지 않는다. JWT 자체도 self-contained 토큰이기 때문에, 서버가 클라이언트 상태를 별도로 저장하지 않고 서명 검증만으로 인증을 완료할 수 있다.
Stateless하지 않은 부분
문제는 토큰 검증 시점에 있다. JwtAuthenticationFilter에서 아래와 같은 조회가 발생한다.
if (Boolean.TRUE.equals(redisTemplate.hasKey("blacklist:" + token))) {
매 요청마다 Redis에 블랙리스트 조회를 수행한다. 이 시점에서 서버는 어떤 토큰이 무효화됐는지라는 상태를 유지하게 된다.
순수한 stateless 구조라면 토큰만으로 유효성 판단이 완결되어야 한다. 블랙리스트 확인은 이 조건을 위반한다.
왜 이 방식을 선택할 수밖에 없는가
순수 stateless JWT에는 근본적인 한계가 있다. JWT는 만료 시각이 지나기 전에 서버가 강제로 무효화할 수단이 없다.
로그아웃, 토큰 탈취 대응, 강제 세션 종료 같은 기능은 서버 측 상태 없이 구현이 불가능하다. 이 상태를 저장하는 방식으로 블랙리스트 또는 화이트리스트 중 하나를 선택해야 하는데, Redis 블랙리스트 방식이 업계에서 가장 보편적으로 채택된다.
결국 HTTP 세션 의존성은 제거했지만, 토큰 폐기(revocation)를 위한 서버 상태는 불가피하게 남아 있는 구조다.
정리
세션 기반 인증은 아니다. 다만 Redis 블랙리스트 조회가 매 요청에 포함되어 있기 때문에, 순수한 의미의 stateless와는 거리가 있다. 토큰 폐기 기능을 위한 트레이드오프를 명시적으로 수용한 구조라고 이해하면 된다.
'Projects > [Spring] Coffee Shop Project' 카테고리의 다른 글
| [트러블슈팅] 포인트 충전이 안되는 문제 해결하기 (0) | 2026.04.05 |
|---|---|
| [트러블슈팅] : Redis 캐시 역직렬화 실패 - 기본 생성자가 없는 경우 (0) | 2026.04.05 |
| [트러블슈팅] Spring Boot 4.x 업그레이드 시 Jackson 패키지 변경 주의하기 (0) | 2026.04.05 |
| [트러블슈팅] UnnecessaryStubbingException 해결하기 (0) | 2026.04.05 |
| [트러블슈팅] soft delete된 메뉴의 인기 랭킹 처리, 어떻게 할까? (0) | 2026.04.05 |