콘텐츠로 건너뛰기

[JWT] Access / Refresh 토큰 이원화

JWT 인증과 Access / Refresh 토큰 이원화 구조 분석

JWT(JSON Web Token)는 기본적으로 암호화(Encryption)가 아닌 서명(Signature)을 기반으로 작동하므로, 토큰 내부의 Payload(데이터)가 제3자에게 노출될 수 있습니다.
이를 보완하기 위해 HTTPS 통신을 통한 전구간 암호화Access / Refresh 토큰 이원화 전략이 필수적으로 사용됩니다.

“Access 토큰이 탈취당하면 유효기간 동안 무방비 아닌가요?”

결론부터 말씀드리면 맞습니다. Access 토큰이 살아있는 동안은 해커가 정상적인 사용자로 위장하여 API를 호출해도 서버는 이를 가려내기 어렵습니다.
JWT는 서버가 세션을 유지하지 않는 ‘Stateless(무상태)‘ 특성을 가지므로, 한 번 발급된 토큰을 서버가 임의로 원격 제어하여 만료시키는 것이 까다롭기 때문입니다.

그럼에도 불구하고 이원화 전략을 사용하는 목적은 “피해 규모와 노출 시간을 최소화”하는 것에 있습니다.
Access 토큰의 수명을 극단적으로 단축: 대개 30분 ~ 1시간 정도로 설정합니다. 탈취당하더라도 해커가 활동할 수 있는 시간을 최소화합니다.
Refresh 토큰의 안전한 보관: 수명이 긴 Refresh 토큰(예: 2주)은 엄격한 보안 환경에 보관하며, 오직 Access 토큰을 재발급할 때만 제한적으로 사용합니다.

Access / Refresh 토큰 인증 흐름

두 토큰은 유기적으로 작동하며 사용자의 편의성(로그인 유지)과 보안성을 동시에 충족합니다.

Access / Refresh 토큰 인증 흐름

① 최초 로그인

  • 사용자가 인증에 성공하면 서버는 수명이 짧은 Access 토큰과 수명이 긴 Refresh 토큰을 발급합니다.
  • 이때 서버는 일반적으로 Refresh 토큰의 고유 값이나 해시를 데이터베이스(예: Redis)에 기록해 둡니다.

② 일반적인 데이터 통신

  • 클라이언트는 모든 HTTP 요청 헤더(Authorization: Bearer <Access_Token>)에 Access 토큰을 실어 보냅니다.
  • 서버는 DB를 조회하지 않고 토큰의 서명(Signature)만 복호화하여 유효성을 검증하므로, 빠른 처리가 가능합니다.

③ Access 토큰 만료 및 자동 갱신

  • Access 토큰이 만료되면 서버는 401 Unauthorized 에러를 반환합니다.
  • 클라이언트(프론트엔드)의 Interceptor(예: Axios Interceptor)가 이 에러를 감지하여, 백그라운드에서 Refresh 토큰을 서버의 재발급 API로 전송합니다.
  • 서버는 전달받은 Refresh 토큰이 DB에 저장된 것과 일치하는지 확인한 후, 새로운 Access 토큰을 발급합니다. 이 과정 덕분에 사용자는 끊김 없이 서비스를 이용할 수 있습니다.

유효기간 내 탈취 위험을 방어하는 추가 보안 전략

실무에서는 Access 토큰의 한계를 보완하기 위해 아래 기술들을 결합하여 아키텍처를 설계합니다.

1. RTR (Refresh Token Rotation)

Refresh 토큰을 일회용으로 만드는 가장 강력한 보안 기법 중 하나.

  • 클라이언트가 Refresh 토큰을 사용해 새로운 Access 토큰을 요청할 때, Refresh 토큰도 함께 새 것으로 갱신하여 교체해 줍니다.
  • 만약 해커가 Refresh 토큰을 탈취하여 먼저 사용했다면, 이후 진짜 사용자가 기존 Refresh 토큰으로 접근했을 때 서버는 “이미 사용된 토큰이 재사용됨“을 감지합니다.
  • 서버는 이를 해킹 시도로 간주하고, 해당 사용자와 관련된 모든 토큰(Access, Refresh) 및 세션을 강제 만료(DB에서 삭제)시켜 추가 피해를 원천 차단합니다.

2. Redis 기반 Blacklist (블랙리스트) 관리

사용자가 로그아웃을 하거나 분실 신고를 했을 때 대응하는 방법.

  • 폐기해야 할 Access 토큰의 고유 ID(jti 클레임 등)를 남은 유효기간만큼 Redis에 블랙리스트로 등록합니다.
  • 서버는 API 요청을 받을 때마다 해당 토큰이 블랙리스트에 있는지 확인합니다.
    유효기간이 남아있더라도 즉시 접근을 거부할 수 있습니다.

단점: 이 방식을 도입하면 JWT의 핵심 장점인 ‘DB 조회 없는 Stateless 인증’이 다소 희석됨.

3. 저장소의 격리 및 차별화

토큰이 클라이언트 환경에서 탈취되는 경로(XSS, CSRF 공격 등)를 차단하기 위한 저장 전략.

구분추천 저장 위치보안 특징
Access 토큰JavaScript 내장 변수 (Recoil, Redux 등) 또는 LocalStorageAPI 요청마다 빈번하게 읽어야 하므로 접근이 용이해야 함. 수명이 짧으므로 상대적으로 위험 노출도가 적음.
Refresh 토큰httpOnly 및 Secure 옵션이 적용된 CookieJavaScript 코드로 접근이 원천 차단(XSS 방어)됩니다. 브라우저가 토큰 재발급 API 주소로 요청을 보낼 때만 자동으로 쿠키를 포함하므로 매우 안전합니다.

요약

JWT 환경에서 유효기간이 남아있는 Access 토큰의 무단 사용을 완벽하게 실시간으로 막는 것은 기술적 구조상 까다롭습니다.
따라서 현대 웹 아키텍처는
① Access 토큰의 생명 주기를 매우 짧게 가져가고,
② 마스터키 역할을 하는 Refresh 토큰을 httpOnly쿠키와 RTR 기법으로 철저히 격리·보호하는 방식
을 채택합니다.
그리고 이 모든 과정은 네트워크 패킷 탈취를 막는 HTTPS(TLS) 암호화 레이어 위에서 실행되어야 비로소 안전성이 완성됩니다.

이 글을 통해 JWT 개선방법에 대한 이해가 되었길 바랍니다.

0 글이 마음에 드시면 하트를 눌러주세요! 행복한 고민이 됩니다!

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Exit mobile version