JWT는 세 파트(Header, Payload, Signature)로 구성된다.
토큰 기반의 인증 시스템은 인증받은 사용자들에게 토큰을 발급하고, 서버에 요청을 할 때 헤더에 토큰을 함께 보내도록 하여 유효성 검사를 한다.
더이상 사용자의 인증 정보를 서버나 세션에 유지하지 않고 클라이언트 측에서 들어오는 요청만으로 작업을 처리한다.
즉, 서버 기반의 인증 시스템과 달리 상태를 유지하지 않으므로 Stateless한 구조를 갖는다.
1. 사용자가 로그인을 성공하면 서버에서 JWT형태의 암호화된 토큰을 발급(생성)한다.
2. 생성된 토큰(암호화 된 JWT)를 클라이언트(브라우저에 보낸다.
3. 사용자의 local storage에 JWT(access token, refresh token)를 저장한다.
4. 브라우저는 모든 request의 헤더에 access token을 함께 전송한다.
5. 서버는 클라이언트(브라우저가 보낸 access token을 식별하고 유효하다면, 원하는 응답을 제공해준다.
JWT는 서버 측에서 토큰을 추적하는 게 아니기 때문에 편리할 수 있으나, 그렇기 때문에 토큰을 탈취당하면, 토큰을 무효화할 방법이 없다.
방지하기 위해 토큰의 수명을 30분 정도로 짧게 잡을려고 한다.
그렇게 되면 사용자는 자주 로그인을 통해 토큰을 재발급 받아야 한다. (사용성 불편)
그래서 토큰을 Acess Token과 Refresh Token 분리해서 전달한다.
Refresh Token은 Access Token과 똑같은 형태의 JWT이다. 처음에 로그인을 완료 했을 때 Access Token과 동시에 발급되는 Refresh Token은 긴 유효기간을 가지면서, Access Token이 만료 됐을 때 새로 발급해주는 key가 된다.
예시
Access Token은 유효기간이 30분, Refresh Token은 유효기간이 2주를 부여한다.
사용자는 로그인을 하고 Access Token과 Refresh Token을 받는다.
클라이언트는 Refresh Token을 안전한 곳(Local Storage) 에 저장하고, API 요청은 Access Token을 가지고 할 수 있다.
30분이 지나 토큰이 만료되면 Refresh Token을 서버에 보냄으로써 새로운 Access Token을 발급받을 수 있게 되고, 발급받은 Access Token으로 다시 API요청을 할 수 있게 된다.
Refresh token도 탈취 당하면 똑같이 보안상 취약점이 생긴다.
Access token이 api 요청 시마다 http통신을 통해 노출이 되는 반면, Refresh token은 Access token이 만료 됐을 경우만 네트워크 통신을 통해 서버로 보내기 때문에 탈취될 위험이 현저히 적다.
[참고] https://d-dual.tistory.com/3
[참고] https://velog.io/@hoo00nn/Token-%EC%9D%B8%EC%A6%9D-%EB%B0%A9%EC%8B%9D%EC%9D%B4%EB%9E%80
[참고] https://mangkyu.tistory.com/55
[참고] https://millo-l.github.io/JWT-%EA%B8%B0%EB%B0%98-%EC%9D%B8%EC%A6%9D%EB%B0%A9%EC%8B%9D/