JWT Access Token과 Refresh Token

✒️ 2025-05-16 09:06 내용 수정


참고 자료 : Access Token과 Refresh Token 원리, What Are Refresh Tokens and How to Use Them Securely

Access Token

Authentication을 진행하고 사용자에게 발급하는 Token

Refresh Token

Access Token의 재발급에 관여하는 Token


Refresh Token 발급 예시

  1. 클라이언트가 처음으로 로그인 했을 때 서버에서 Access Token과 Refresh Token을 함께 발급한다.
  2. 서버의 DB에 Refresh Token을 저장한다.
  3. 클라이언트는 Access Token과 Refresh Token을 cookie, session storage, web stroage 등에 저장하고, 요청을 보낼 때 Header에 Token을 담아 전송한다.
  4. 만약 클라이언트가 Token들과 함께 요청을 보냈을 때 Access Token이 만료되었다면, 서버에선 요청으로 온 Refresh Token과 DB에 저장된 Refresh Token을 비교하여 둘이 일치했을 때 Access Token을 새로 발급한다.
  5. 만약 Refresh Token도 만료 되었다면 사용자는 클라이언트에서 새로 로그인하여 Access Token과 Refresh Token을 새로 발급 받는다.
    • Access Token은 유효한데 Refresh Token이 만료 되었다면 Refresh Token을 재발급 한다.
  6. 사용자가 로그아웃 한다면 Access Token과 Refresh Token을 모두 만료 시킨다.

jwt_refresh_token.png


Token 저장과 보안 문제

참고 자료 : JWT Refresh Token 저장에 관한 자료, JWT는 어디에 저장해야 할까, Access Token과 Refresh Token을 어디에 저장하고 어떻게 교환해야 할까, All you need to know about storing jwt tokens securly in the frontend

  1. 예상 보안 문제
    • XSS(Cross Site Scripting) : 악의적인 사용자가 웹 사이트에 악성 Script를 삽입할 수 있는 취약점
    • CSRF(Cross Site Request Forgery) : 사용자가 의도치 않게 공격자가 의도한 행동을 하게 만드는 공격
  2. 클라이언트 저장소 후보
    • Local Storage : CSRF 공격으로부터 안전하지만 XSS 공격에 취약할 수 있다.
      • 세션이 끝나더라도 데이터가 유지되는 특성이 있지만, 브라우저 종료 시 데이터가 삭제되지 않아 보안에 민감한 정보를 저장하지 않는 것이 좋다.
      • 많은 용량의 데이터를 저장할 수 있다.
    • Cookie : httpOnlysecure 옵션을 사용 시 Javascript로 cookie 접근이 불가능하여 XSS 공격으로부터 비교적 안전하다.
      • 용량이 제한되어 있어 적은 양의 데이터만 저장할 수 있다.
      • 요청할 때마다 cookie를 서버로 전송해야 하므로 트래픽이 증가할 수 있다.
  3. 정리 : 참고 자료들을 통해Token을 Local storage에 저장해두면 간편하긴 하지만 악성 Script 공격에 의해 XSS 공격에 대비하기 어렵다.
    • cookiehttpOnlysecure 옵션을 사용하면 상대적으로 안전하나, 큰 용량의 데이터를 저장할 수 없다.
  4. 결론 : Access Token은 프론트 엔드의 로컬 변수에 저장하여 사용자가 다른 탭으로 이동하거나 새로고침 시 휘발될 수 있도록 한다.
    • Refresh Token은 httpOnly, secure=true, SameSite=strict 혹은 SameSite=Lax로 설정된 cookie에 저장한다.

Refresh Token 한계점

참고 자료 : Access Token의 문제점과 Refresh Token, JWT 탈취 대비 - SXX, CSRF, RTR, 3 Scenarios Where You Can Store JWT Token in Your DB

  1. 만료되지 않은 Access Token이 탈취 당했다면 해당 Token이 유효한 시간 동안은 서버에서 악용을 막을 수 없다.
    • 많은 자료에서 공통적으로 나오는 이야기로, 이를 대비해 Access Token을 직접 만료 시키는 방법들에 대한 고찰도 많았다.
    • 방법들 중 하나로 서버에서 Access Token 발급 기록을 추적하는 것이 있는데, 사실상 JWT를 쓰는 의미가 없어 session을 사용하는 것이 낫다는 결론이 나왔다.
    • stateless 특징을 사용해 Token 기반 인증을 사용하는 이유가 확장성 및 DB 접근과 관련된 경제성 이점을 챙기기 위함인데, 결국 서버에서 기록을 추적하는 시점에서 이런 이점을 버리는 셈이다.
  2. 만료 기한이 짧고 탈취 위험이 있는 Access Token의 보안 문제를 위해 사용하는 Refresh Token이 탈취 되었을 때는 어떻게 처리해야 하는지도 문제이다.
    • 서버에서 DB에 Refresh Token을 저장하여 Access Token 재발급 요청이 왔을 때 요청의 Refresh Token과 DB의 Refresh Token을 비교하는 방법이 있다.
    • 하지만 DB에서 이를 비교한다고 해도 공격자가 유효한 Refresh Token을 가지고 Access Token을 요청한다면 서버에선 이 Refresh Token이 탈취 당한 Token인지 아닌지 확인할 방법이 없다.
  3. Refresh Token의 경우 RTR(Refresh Token Rotation) 기법을 사용하여 Refresh Token을 한 번만 사용하는 방법을 적용하여 Refresh Token 재사용을 막을 수 있으나, 이 방법 역시 처음부터 Refresh Token이 탈취되거나 Access Token 자체가 탈취 당했을 때의 문제를 완벽하게 막을 수 없다.

RTR(Refresh Token Rotation)

참고 자료 : An in-depth look at refresh tokens in the browser, Securing Single Page Applications with Refresh Token Rotation, Access Token과 Refresh Token 그리고 RTR 기법에 대해서 알아보자.

rtr_flow.png

애플리케이션이 Refresh Token 보호가 적용되었을 때 Refresh Token을 사용하는 타임 라인
처음 Access Token과 Refresh Token을 발급 받은 뒤, Token을 다시 발급 받을 때 새 Access Token과 Refresh Token을 발급 받는다.

rtr_flow_detection.png

공격자가 훔친 Refresh Token을 다시 사용했을 때의 타임 라인
공격자가 그림의 Refresh Token 2를 훔친 뒤 사용했을 때 이미 RT2는 사용되어 새 Access Token과 Refresh Token을 발급 받은 상태이므로, STS(Security Token Service)에서 재사용을 감지해 AT3를 폐기한다.

rtr_flow_detection 2.png

애플리케이션이 Refresh Token을 재사용할 때의 타임 라인
공격자가 RT2를 훔친 뒤 사용하여 새 AT3와 RT3를 발급 받았을 때 애플리케이션이 RT2를 사용하여 AT3와 RT3를 받으면 STS에서 RT2의 재사용을 감지해 RT3를 폐기한다.