JWT Access Token과 Refresh Token
✒️ 2025-05-16 09:06 내용 수정
참고 자료 : Access Token과 Refresh Token 원리, What Are Refresh Tokens and How to Use Them Securely
- JWT는 JWT(Json Web Token) 참고.
Access Token
Authentication을 진행하고 사용자에게 발급하는 Token
- 이 Token으로 사용자는 서버에 데이터를 요청할 수 있다.
- Access Token은 한 번 발급된 이후에 서버에 저장하지 않고 토큰 자체로 사용자 권한을 인증한다.
- Token 인증 방식에선 Session과 다르게 Stateless하며, 이는 서버가 상태를 보관하지 않는다는 뜻이다.
- 따라서 Access Token을 제 3자에게 탈취 당하면 보안에 취약해진다.
- JWT(Json Web Token)#JWT 사용 시 주의 사항에도 있지만 Token에 중요한 정보를 저장하면 안되며, 필요 이상의 유효 기간을 설정하면 위험하다.
- Token의 유효 기간을 짧게 설정한다면 탈취 당한 Token의 남용 문제를 해결할 수 있으나, 유효 기간이 짧기 때문에 사용자는 자주 로그인해서 새 Token을 받아야 한다.
- 보안 문제로 짧은 유효 기간을 가진 Access Token의 단점을 보완하기 위해 Refresh Token을 함께 사용한다.
Refresh Token
Access Token의 재발급에 관여하는 Token
- Access Token과 마찬가지로 JWT이나, Access Token을 재발급하기 위해 사용되는 추가적인 Token이다.
- Refresh Token이 유효하고 만료되지 않는 한 클라이언트에서 새 Access Token을 발급 받을 수 있다.
- OAuth 2.0 framework와 같은 인증-인가 방법에선 Access Token과 Refresh Token을 정의하며, SAML과 같은 다른 신원 확인 프로토콜이나 framework에선 Access Token과 Refresh Token 개념이 적용되지 않는다.
- Token의 형태는 Access Token과 같은 JWT 형식, UUID 형식, 또는 암호화된 간단한 String으로 생성할 수 있다.
Refresh Token 발급 예시
- Authorization Server와 Resource Server가 하나일 때
- 클라이언트가 처음으로 로그인 했을 때 서버에서 Access Token과 Refresh Token을 함께 발급한다.
- 서버의 DB에 Refresh Token을 저장한다.
- 클라이언트는 Access Token과 Refresh Token을 cookie, session storage, web stroage 등에 저장하고, 요청을 보낼 때 Header에 Token을 담아 전송한다.
- 만약 클라이언트가 Token들과 함께 요청을 보냈을 때 Access Token이 만료되었다면, 서버에선 요청으로 온 Refresh Token과 DB에 저장된 Refresh Token을 비교하여 둘이 일치했을 때 Access Token을 새로 발급한다.
- 만약 Refresh Token도 만료 되었다면 사용자는 클라이언트에서 새로 로그인하여 Access Token과 Refresh Token을 새로 발급 받는다.
- Access Token은 유효한데 Refresh Token이 만료 되었다면 Refresh Token을 재발급 한다.
- 사용자가 로그아웃 한다면 Access Token과 Refresh Token을 모두 만료 시킨다.
- Authorization Server와 Resource Server가 나뉘어져 있을 때
- 사진 원본 자료 : Learn With Ifte's Implementing Secure Refresh Tokens in Spring Boot | #1 | Spring Boot JWT

Token 저장과 보안 문제
참고 자료 : JWT Refresh Token 저장에 관한 자료, JWT는 어디에 저장해야 할까, Access Token과 Refresh Token을 어디에 저장하고 어떻게 교환해야 할까, All you need to know about storing jwt tokens securly in the frontend
- JWT를 사용하면 Token으로 Authentication을 진행하기에 이를 탈취 당하면 공격자가 피해자의 권한을 남용하는 문제가 발생할 수 있다.
- 따라서 이를 탈취하기 어렵게 설정하는 것이 중요하고, 탈취 당했을 때의 대처 역시 중요하다.
- 그렇다면 서버로부터 Access Token과 Refresh Token을 발급 받는 것은 성공했는데, 이 둘을 클라이언트의 어디에 저장하고 요청을 보낼 때 어떻게 보내야 보안 문제가 덜 발생할 수 있는지 알아야 했다.
- 예상 보안 문제
- XSS(Cross Site Scripting) : 악의적인 사용자가 웹 사이트에 악성 Script를 삽입할 수 있는 취약점
- CSRF(Cross Site Request Forgery) : 사용자가 의도치 않게 공격자가 의도한 행동을 하게 만드는 공격
- 클라이언트 저장소 후보
Local Storage: CSRF 공격으로부터 안전하지만 XSS 공격에 취약할 수 있다.- 세션이 끝나더라도 데이터가 유지되는 특성이 있지만, 브라우저 종료 시 데이터가 삭제되지 않아 보안에 민감한 정보를 저장하지 않는 것이 좋다.
- 많은 용량의 데이터를 저장할 수 있다.
Cookie:httpOnly와secure옵션을 사용 시 Javascript로 cookie 접근이 불가능하여 XSS 공격으로부터 비교적 안전하다.- 용량이 제한되어 있어 적은 양의 데이터만 저장할 수 있다.
- 요청할 때마다 cookie를 서버로 전송해야 하므로 트래픽이 증가할 수 있다.
- 정리 : 참고 자료들을 통해Token을
Local storage에 저장해두면 간편하긴 하지만 악성 Script 공격에 의해 XSS 공격에 대비하기 어렵다.cookie는httpOnly와secure옵션을 사용하면 상대적으로 안전하나, 큰 용량의 데이터를 저장할 수 없다.
- 결론 : Access Token은 프론트 엔드의 로컬 변수에 저장하여 사용자가 다른 탭으로 이동하거나 새로고침 시 휘발될 수 있도록 한다.
- Refresh Token은
httpOnly,secure=true,SameSite=strict혹은SameSite=Lax로 설정된 cookie에 저장한다.
- Refresh Token은
Refresh Token 한계점
참고 자료 : Access Token의 문제점과 Refresh Token, JWT 탈취 대비 - SXX, CSRF, RTR, 3 Scenarios Where You Can Store JWT Token in Your DB
- 만료되지 않은 Access Token이 탈취 당했다면 해당 Token이 유효한 시간 동안은 서버에서 악용을 막을 수 없다.
- 많은 자료에서 공통적으로 나오는 이야기로, 이를 대비해 Access Token을 직접 만료 시키는 방법들에 대한 고찰도 많았다.
- 방법들 중 하나로 서버에서 Access Token 발급 기록을 추적하는 것이 있는데, 사실상 JWT를 쓰는 의미가 없어 session을 사용하는 것이 낫다는 결론이 나왔다.
- stateless 특징을 사용해 Token 기반 인증을 사용하는 이유가 확장성 및 DB 접근과 관련된 경제성 이점을 챙기기 위함인데, 결국 서버에서 기록을 추적하는 시점에서 이런 이점을 버리는 셈이다.
- 만료 기한이 짧고 탈취 위험이 있는 Access Token의 보안 문제를 위해 사용하는 Refresh Token이 탈취 되었을 때는 어떻게 처리해야 하는지도 문제이다.
- 서버에서 DB에 Refresh Token을 저장하여 Access Token 재발급 요청이 왔을 때 요청의 Refresh Token과 DB의 Refresh Token을 비교하는 방법이 있다.
- 하지만 DB에서 이를 비교한다고 해도 공격자가 유효한 Refresh Token을 가지고 Access Token을 요청한다면 서버에선 이 Refresh Token이 탈취 당한 Token인지 아닌지 확인할 방법이 없다.
- Refresh Token의 경우 RTR(Refresh Token Rotation) 기법을 사용하여 Refresh Token을 한 번만 사용하는 방법을 적용하여 Refresh Token 재사용을 막을 수 있으나, 이 방법 역시 처음부터 Refresh Token이 탈취되거나 Access Token 자체가 탈취 당했을 때의 문제를 완벽하게 막을 수 없다.
- 결국 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 방법은 Refresh Token을 한 번 사용할 때만 유효하고, 다음에 Refresh Token을 사용할 땐 새로운 Access Token과 Refresh Token을 발급하여 같은 Refresh Token을 재사용할 수 없도록 한다.

애플리케이션이 Refresh Token 보호가 적용되었을 때 Refresh Token을 사용하는 타임 라인
처음 Access Token과 Refresh Token을 발급 받은 뒤, Token을 다시 발급 받을 때 새 Access Token과 Refresh Token을 발급 받는다.
- 참고 자료에 따르면 단순히 Refresh Token을 재발급 하는 것 자체가 보안을 향상 시키는 것이 아니고, Security Token Service에서 Refresh Token이 한 번 이상 사용된 것을 감지하여 Refresh Token을 폐기(revoke) 시키는 것이 RTR의 보안 핵심 부분이라고 한다.
- 그리고 자손 Refresk Token들도 항상 취소 시켜 token 체인이 더 이상 유효하지 않게 만드는 것도 중요하다.

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

애플리케이션이 Refresh Token을 재사용할 때의 타임 라인
공격자가 RT2를 훔친 뒤 사용하여 새 AT3와 RT3를 발급 받았을 때 애플리케이션이 RT2를 사용하여 AT3와 RT3를 받으면 STS에서 RT2의 재사용을 감지해 RT3를 폐기한다.
- RTR을 사용하면 Refresh Token의 재사용을 막을 수 있으나, 공격자가 처음부터 애플리케이션으로부터 Refresh Token을 탈취하여 사용한다면 이후 재발급 받는 Access Token도 공격자가 사용할 수 있다.
- 또한 Access Token은 종종 self-contained JWT 토큰이기에, 이런 Token들은 API가 보안 결정을 내리는 데에 필요한 정보들을 포함해서 참조 토큰보단 유연성이 좋으나 관리하기 훨씬 어렵다.
- Security Token Service은 self-contained Token이 사용될 때 유효성 검증에 관여하지 않기에 이런 Token들은 쉽게 폐기할 수 없다.
- 즉 Refresh Token의 한계인 Access Token이 탈취 당했을 때의 문제를 해결하기 어렵다.