로그인 / 회원가입 페이지 구현 중에 궁금한 점이 생겼다.
Access Token과 Refresh Token이 정확히 뭐고 왜 필요하지?
보통 서버가 클라이언트 인증을 확인하는 방식은 대표적으로 쿠기, 세션, 토큰 3가지 방식이 있다.
토큰에 대해 알아보기 전에 간단히 짚고 넘어가자.
쿠키는 Key-Value 형식의 문자열 덩어리이다.
클라이언트가 웹사이트를 방문할 경우, 그 사이트의 서버를 통해 클라이언트의 브라우저에 설치되는 작은 기록 정보 파일이다. 각 사용자마다 브라우저에 정보를 저장하니 고유 정보 식별이 가능하다.
쿠키의 보안적인 이슈 때문에 세션은 비밀번호 등 클라이언트의 민감한 인증 정보를 브라우저가 아닌 서버 측에서 저장하고 관리하는 것이다. 서버의 메모리에 저장하거나, 로컬 파일이나 DB에 저장하기도 한다.
JWT(Json Web Token)은 Json 객체에 인증에 필요한 정보들을 암호화시킨(비밀 키로 서명한) 토큰으로,
JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 인터넷 표준 인증 방식이다.
JWT는 JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것이고, 토큰 내부에는 위변조 방시를 위해 개인키를 통한 전자서명도 들어있다.
JWT는 . 을 기준으로 좌측부터 Header, Payload, Signature를 의미한다.

![]()
클라이언트는 ID, PW를 입력하여 서버에 로그인 인증 요청(POST)을 보낸다.
서버에서 클라이언트로부터 인증 요청을 받으면, Header, PayLoad, Signature을 정의한다. Hedaer, PayLoad, Signature를 각각 Base64로 한 번 더 암호화하여 JWT, Access Token, Refresh Token을 생성하고 이를 쿠키에 담아 클라이언트에게 발급한다.
클라이언트는 서버로부터 받은 JWT를 로컬 스토리지에 저장한다. (쿠키나 다른 곳에 저장할 수도 있다.)
API를 서버에 요청할때 Authorization header에 Access Token을 담아서 보낸다.
서버는 Access Token을 검증하고 통과하면 데이터 응답을 보낸다.
클라이언트가 만료된 Access Token을 이용해 요청을 보내면 서버는 재발행요청을 한다.
재발행 요청은 만료된 Access Token과 유효한 RefreshToken 값을 URL/auth/reissue 로 POST 요청을 보낸다.
서버에서는 RefreshToken을 검증하고 다시 AccessToken과 RefreshToken 값을 사용자에게 넘겨준다.
다른 유저가 Payload를 임의로 수정했을 때, 수정한 토큰을 서버에 요청을 보내면 서버는 유효성 검사를 시행한다.
대조 결과가 일치하지 않으면 유저의 정보가 임의로 조작되었음을 알 수 있다.
서버는 토큰 안에 들어있는 정보가 무엇인지 아는 것보다 해당 토큰이 유효한 토큰인지 확인하는 것이 중요하다.
❗️주의할 점
JWT는 Base64로 암호화 하는데 디버거를 사용하면 인코딩 된 HWT를 1초만에 복호화할 수 있다.
그러므로 Payload에는 비밀번호와 같은 민감한 정보는 넣지 말아야 한다. 토큰의 목적은 정보 보호가 아닌, 위조 방지이다!!
JWT과 Access Token 뭔지 이제 좀 알겠다. 그럼 Refresh Token의 역할은 뭘까?
Access Token 만으로는 제 3자에게 탈취당할 경우 보안에 취약하다. JWT는 발급한 후 삭제가 불가능하기에, 토큰에 유효시간을 부여하는 식으로 탈취 문제에 대응해야 한다. 유효시간이 짧아질수록 보안에 좋겠지만, 그만큼 로그인을 자주 해서 Token을 새롭게 발급받아야 한다.
그래서 유효기간을 짧게 하면서 보안성을 높이기 위한 역할을 Refresh Token이 한다.
이름이 다르지만 형태 자체는 Refresh Token은 Access Token과 똑같은 JWT다. 단지 Access Token은 접근에 관여하는 토큰이고, Refresh Token은 재발급에 관여하는 토큰이다.
기본적으로 로그인 같은 과정을 하면 Access Token과 Refresh Token을 모두 발급하고, Refresh Token만 서버의 DB에 저장하고, 두 토큰 모두 쿠키 혹은 웹스토리지에 저장한다.
사용자가 인증이 필요한 API에 접근하고자 하면, 가장 먼저 토큰을 검사한다.
Access Token, Refresh Token 모두 만료 -> Error -> 재 로그인 후 둘 다 새로 발급
Access Token 만료, Refresh Token 유효 -> 클라이언트(쿠키, 웹스토리지)에 저장되어있는 refresh token과 서버 DB에 저장되어있는 refresh token 일치성을 확인한 뒤 access token 재발급
Access Token 유효, Refresh Token 만료 -> access token이 유효하다라는 것은 이미 인증된 것과 마찬가지니 바로 refresh token 재발급
Access Token, Refresh Token 모두 유효 -> 정상 처리
출처:
https://inpa.tistory.com/entry/WEB-📚-JWTjson-web-token-란-💯-정리 [Inpa Dev 👨💻:티스토리],
https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-Access-Token-Refresh-Token-%EC%9B%90%EB%A6%AC-feat-JWT,
https://onejunu.tistory.com/137,
https://dreamcode.tistory.com/444?category=1050903