고민보단 실천을

JWT Refresh Token Rotation 설계: 재사용 탐지(reuse detection)로 탈취 대응하기 본문

카테고리 없음

JWT Refresh Token Rotation 설계: 재사용 탐지(reuse detection)로 탈취 대응하기

Just-Do-It 2026. 2. 28. 13:59

JWT Refresh Token Rotation 설계: 재사용 탐지(reuse detection)로 탈취 대응하기

Access token을 짧게 가져가면 결국 refresh token이 중요해집니다. 그런데 refresh token을 '고정'으로 쓰면 탈취 시 피해가 커집니다. 이 글은 검색 수요가 높은 키워드인 refresh token rotation재사용 탐지(reuse detection)를 중심으로, 설계 포인트를 실무적으로 정리합니다.

Refresh token rotation
rotation은 '새 refresh를 발급하고 이전 refresh를 폐기'하는 방식으로 탈취 피해를 줄입니다.

옵션/핵심 요소(3~6개)

항목의미언제 쓰는지(실무 상황)
Refresh rotation갱신 시 새 refresh 발급refresh 탈취 피해를 줄이기 위해 기본으로 고려
Reuse detection이미 폐기된 refresh 재사용 탐지탈취자가 예전 refresh로 갱신을 시도할 때 세션을 강제 종료
Token family동일 세션 묶음한 기기/세션 단위로 모두 폐기해야 할 때 추적에 사용
저장 방식서버가 refresh 상태를 기억rotation을 하려면 보통 refresh 토큰을 DB/Redis에 저장해 상태 관리
쿠키/스토리지클라이언트 보관 위치웹은 HttpOnly 쿠키 선호, 모바일은 보안 저장소 사용

권장 플로우(간단 버전)

// 1) 로그인 성공 시
- access(짧게) + refresh(길게) 발급
- refresh는 서버에 해시로 저장(원문 저장 지양)

// 2) /auth/refresh 호출 시
- refresh 검증 + DB에서 '현재 유효한 refresh'인지 확인
- 새 refresh 발급 + 기존 refresh 폐기(rotate)
- access도 새로 발급

// 3) reuse detection(중요)
- 폐기된 refresh가 다시 들어오면: 세션 전체 폐기 + 재로그인 요구

문제 상황(정확히 1개)

상황: 운영에서 간헐적으로 사용자가 갑자기 로그아웃되고, 어떤 사용자는 refresh가 연속으로 실패(401)한다.

원인: refresh rotation을 도입했는데, 클라이언트가 동시 요청(예: 여러 탭, 자동 재시도)으로 같은 refresh를 두 번 사용해버렸다. 첫 번째 요청이 rotation으로 refresh를 폐기한 뒤 두 번째 요청이 들어오면 reuse로 간주되어 세션이 끊길 수 있다.

해결: 클라이언트에서 refresh 요청을 싱글플라이트(동시 1회)로 만들고, 서버는 짧은 그레이스(1회용) 처리 또는 idempotency 전략을 검토한다. 무엇보다 reuse detection을 로깅해 실제 탈취인지 동시성 문제인지 구분한다.

예방 팁: refresh는 '항상 한 번만 날린다'는 클라이언트 규칙을 강제하고, 서버는 refresh 토큰을 해시로 저장하며, reuse 이벤트는 보안 이벤트로 별도 관제한다.

참고/출처

Comments