본문으로 건너뛰기
개발 머꼬
개발 노트보안
hohyeon.dev17

JWT로 바꿨더니 로그아웃이 즉시 안 되는 이유

  • #Auth
  • #Engineering Note
  • #JWT
  • #Security

문제 발생

세션 기반 인증에서 JWT 기반으로 바꾼 뒤, 사용자가 "로그아웃"을 눌러도 이미 발급된 토큰이 만료 시간까지 계속 유효해서 탈취된 토큰으로 계속 API 접근이 가능한 상태가 됐습니다.

원인 분석

세션 방식은 서버(또는 세션 저장소)가 "이 세션 ID가 유효한가"를 항상 직접 조회합니다. 로그아웃은 그 세션 레코드를 지우는 것이므로 즉시 효력이 있습니다.

JWT는 반대로 설계됐습니다. 토큰 자체에 서명이 있어 서버가 별도 저장소를 조회하지 않고도 토큰의 위변조 여부와 만료 시간만으로 유효성을 검증할 수 있습니다 — 이게 JWT가 수평 확장(여러 서버 인스턴스, 상태 비저장)에 유리한 이유입니다. 하지만 이 특성 때문에 서버는 특정 토큰을 "발급 이후에" 무효화할 방법이 원천적으로 없습니다 — 토큰은 만료 시간이 될 때까지 그 자체로 유효합니다.

해결 방안

JWT의 이 근본적 트레이드오프를 이해하고 설계에 반영해야 합니다.

  1. Access Token의 유효 기간을 짧게 잡습니다(수 분~수십 분). 탈취되더라도 피해 시간을 제한할 수 있습니다.
  2. Refresh Token을 별도로 두고, 이건 서버(DB)에 저장해 상태를 관리합니다. Access Token이 만료되면 Refresh Token으로 새 Access Token을 발급받는 구조로, 로그아웃 시 이 Refresh Token 레코드만 지우면 이후로는 새 Access Token 발급 자체가 막힙니다 — 다만 이미 발급된 Access Token은 원래 유효기간까지는 여전히 유효합니다.
  3. 정말로 즉시 무효화가 필요한 상황(계정 탈취 의심 등)이 있다면, 블랙리스트(무효화된 토큰의 ID를 별도 저장소에 잠깐 저장해두고 검증 시마다 조회)를 둘 수 있습니다 — 다만 이렇게 하면 결국 서버가 상태를 들고 조회해야 해서, JWT의 "상태 비저장" 장점을 일부 포기하는 셈입니다.
  4. 애초에 "즉시 로그아웃이 반드시 필요한가"를 먼저 따져봅니다 — 일반적인 서비스는 짧은 Access Token 유효기간만으로 충분한 경우가 많고, 금융/보안이 민감한 서비스만 블랙리스트 같은 추가 장치가 필요한 경우가 많습니다.
  5. 세션과 JWT 중 어느 게 "더 낫다"가 아니라, 확장성과 즉시 무효화 사이의 트레이드오프를 서비스 요구사항에 맞춰 선택하는 문제입니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.