JWT Token (Access Token, Refresh Token)
우선 Token을 쓰는 이유 부터 알아보도록 하자.
JWT 토큰은 유저의 신원을 확인해주는 정보를 담은 데이터 조각이라고 볼 수 있다. JWT 토큰의 인증 방식 자체가 비밀키로 암호화 하기 때문에 client <ㅡ> Server는 서로 안정적인 통신을 할 수 있다.
하지만 만약에라도 탈취를 당한다면 자신의 신원 자체를 다른 사람에게 뺏기는 것과 같으며 인증을 통과할 수 있기 때문에 위험하다. 따라서 이 토큰 탈취 당했을 때의 위험을 방지하기 위해 토큰의 유효 기간을 두어서 해결한다.
하지만 토큰의 기한이 짧으면 사용자는 토큰을 다시 받기 위해 로그인을 해야하고 길게두면 탈취 방지를 하기에 적합하지 않다. 따라서 JWT 토큰 자체를 2개(access Token, Refresh Token)로 나누어서 유효 기간을 다르게 둔다.
이제 이 두 토큰에 대해서 설명하자면..
- Access Token : 유효기간이 짧으며 평소 API 통신에 사용한다.
- Refresh Token : 유효기간이 길고 만료된 Access Token을 갱신할 때 사용한다.
평소 통신하며 탈취 당할 가능성이 높은 Access Token을 짧게 하고 Refresh Token으로 재발급을 해주는 메커니즘이다.

1. Client에서 로그인에 성공하면 서버에게 Access Token, Refresh Token을 받는다.
2. Client가 Refresh Token과 Access Token을 저장해둔다.
3~4. Client에서 Header(Authorization)에 Access Token을 넣어 API 통신을 하게된다.
5. Client에 있는 Access Token의 유효기간이 만료되어 권한이 사라진다. 그렇게 만료된 Access Token을 보내게되면
6. 서버는 만료된 Access Token을 받기에 Client에게 invalid Token Response(만료된 토큰 응답)을 전달한다.
7. Client는 만료된 Access Token 대신 Refresh Token을 header에 넣어 API를 요청한다.
8. 서버는 Refresh Token을 보고 권한 확인을 하여 Client에게 새로운 Access Token을 전송한다.
그렇다면 Front(나)에서 해야 할일은 어떤 것들이 있을까?
서버에서 인증과 인가를 모두 실행한다면 (Spring Security)
우리가 해야할 일은 위의 과정을 보면 알기 쉬울 것이다. 로그인 요청을 보내는 순간 서버에서 인증 하여 로그인 성공을 하고 서버에게 AccessToken, Refresh Token을 받게 될 것이다. 우리는 이 두 토큰을 저장 해두어야한다. 여기서 이 저장소가 중요하게 될 것인데 이 토큰들은 인증 및 권한 부여에 사용되는 아주 중요한 정보이기에 공격당하기 쉬운 방법으로 저장해두면 절대 안된다. 그래서 현재 내가 생각했을때 가장 좋은 방법은 다음과 같다.
AccessToken : 받아서 local storage에 저장 -> 노출되기 쉽지만 유효 기간이 짧은 토큰이기에 사용성이 넓은 로컬스토리지에 저장하여 필요할 때 마다 Authorization Header에 accessToken을 넣고 API 요청을 하여 사용자 인증이 가능하다.
RefreshToken: 세 가지 방법을 생각해 보았는데
Front에서 관리하는 방법
- Cookie에 저장? -> HTTPOnly, Secure 옵션을 사용하며 CSRF 공격에 대비한다면 나쁘지 않다.
CSRF 공격 : Cross-Site Request Forgery, 사용자가 인증된 대상 사이트로 원하지 않는 HTTP 요청 전송
Back(Server)
사실 Refresh Token은 백엔드에서 관리하는게 용이하지만 accessToken 재발급을 위한 API 요청이 많아진다.
1. 받아서 Session storage에 저장 -> 세션 스토리지는 Client 쪽에서 접근이 불가능하고 서버 측에서만 접근 가능하도록 구성된다. ( 세션에 저장하고 세션 만료 주기를 늘리는 방식이지만 JWT 이용 목적에 적합하지 않다.)
2. Refresh Token을 DB에 저장 -> Refresh Token을 DB에 저장 후 index 값을 쿠키, local storage에 저장하는 방법이다.
client 에서 refresh token을 노출하지 않을 수 있으며, 탈취 당했을 때 해당 토큰 폐기 가능.