JWT는 Stateless라는 말이 왜 반은 거짓인가
JWT는 정말 Stateless일까?
JWT를 설명할 때 가장 자주 등장하는 문장은 이겁니다.
"JWT는 Stateless 인증 방식이다"
이 말은 틀린 말은 아닙니다. 하지만 그대로 믿으면 오해를 낳는 말이기도 합니다.
실무에서 JWT를 제대로 쓰다 보면,
"어? 결국 서버가 뭔가 기억하고 있는데?"
라는 순간을 반드시 마주치게 됩니다.
이 글에서는
- JWT가 왜 Stateless라고 불리는지
- 그 말이 왜 반만 맞는 말인지
- 실무에서는 어떤 지점에서 상태가 다시 생기는지
를 차근히 짚어보려 합니다.
JWT가 Stateless라고 불리는 이유
JWT의 기본 모델은 단순합니다.
요청 ── JWT ──▶ 서버
서버 ── 서명 검증 ──▶ 사용자 신뢰
서버는
- 세션을 저장하지 않고
- 사용자 정보를 조회하지 않으며
- 토큰 자체만 검증합니다
즉,
"이 요청이 누구의 것인지"를 서버 내부 상태 없이 판단할 수 있습니다.
이 지점만 보면 JWT는 분명 Stateless입니다.
Stateless라는 말이 숨기고 있는 전제
JWT가 Stateless일 수 있는 이유는 단 하나입니다.
"토큰이 만료될 때까지 항상 유효하다고 가정한다"
이 가정이 깨지는 순간, Stateless 구조도 함께 흔들립니다.
문제가 되는 질문 하나
실무에서 반드시 나오는 질문이 있습니다.
"이 토큰을 지금 당장 무효화하려면 어떻게 하지?"
- 로그아웃
- 권한 변경
- 계정 정지
- 토큰 탈취 의심
이런 상황에서
"만료될 때까지 기다리면 됩니다"
는 대부분의 서비스에서 현실적인 답이 아닙니다.
로그아웃은 Stateless 모델에 존재하지 않는다
JWT 관점에서 로그아웃은 이상한 개념입니다.
- 서버는 토큰을 저장하지 않음
- 토큰은 만료 전까지 항상 유효
즉,
서버 입장에서 로그아웃은 아무 일도 일어나지 않는 이벤트입니다.
그래서 이 순간부터
"서버가 이 토큰을 기억해야 하나?"
라는 질문이 다시 등장합니다.
상태가 다시 생기는 지점들
1. 토큰 블랙리스트
가장 직관적인 해결책은 이겁니다.
"이 토큰은 더 이상 인정하지 않는다"
이를 위해 서버는
- 무효화된 토큰 목록을 저장하고
- 매 요청마다 이를 조회합니다
이 순간,
서버는 다시 상태를 가지게 됩니다.
2. Refresh Token 전략
실무에서 JWT는 거의 항상 이렇게 사용됩니다.
- Access Token (짧은 수명)
- Refresh Token (긴 수명)
Refresh Token을 사용하는 순간, 서버는 다음 중 하나를 선택해야 합니다.
- Refresh Token을 저장한다
- 사용자별로 관리한다
즉,
**"재발급을 통제하는 상태"**가 필요해집니다.
Stateless는 이 시점에서 더 이상 완전하지 않습니다.
3. 권한 변경과 즉시 반영 문제
JWT Payload에 이런 정보가 들어 있다고 가정해봅니다.
{
"userId": 1,
"role": "ADMIN"
}
- 사용자의 권한이 변경되면?
- 이미 발급된 토큰은?
이 문제를 해결하려면
- 토큰 재발급
- 버전 관리
- 사용자 상태 체크
중 하나가 필요합니다.
이 역시 상태를 요구합니다.
그래서 JWT는 왜 계속 Stateless라고 불릴까?
JWT가 Stateless라고 불리는 이유는
"세션 모델과 비교했을 때 상대적으로 Stateless"
이기 때문입니다.
- 모든 요청마다 세션 조회 ❌
- 사용자 객체 로딩 ❌
- 중앙 세션 저장소 의존 ❌
이걸 하지 않아도 되기 때문에
"Stateless에 가깝다"
라고 표현되는 것입니다.
Stateless는 목표이지, 현실은 아니다
실무에서의 JWT 구조는 보통 이렇습니다.
Access Token: Stateless
Refresh Token: Stateful
즉,
- 요청 인증은 최대한 Stateless하게 처리하고
- 통제와 안전은 상태로 보완합니다
이건 실패가 아니라 타협의 결과입니다.
프론트엔드 알아야 하는 이유
프론트엔드에서는 JWT를 이렇게 느끼기 쉽습니다.
"헤더에 토큰만 넣으면 끝"
하지만 실제로는
- 만료 시점 UX
- 재발급 타이밍
- 로그아웃 처리
전부 이 Stateful 지점과 연결됩니다.
JWT를 Stateless라고만 이해하면
- 로그아웃이 왜 애매한지
- 만료 처리 왜 복잡한지
절대 설명할 수 없습니다.
이 글의 결론
- JWT는 Stateless를 지향한다
- 하지만 완전한 Stateless는 아니다
- 실무에서는 반드시 상태가 다시 생긴다
그래서 더 정확한 표현은
"JWT는 상태를 최소화하려는 인증 방식이다"