Spring Security에 JWT를 적용하다 보니 Access Token 외에 추가로 Refresh Token이 필요하다는 것을 알게 되었다
Refresh Token
정의: 단일 토큰을 사용하는 환경에서의 보안적 위험에 대비하기 위한 토큰
- 이름은 access token / refresh token으로 달라 보이지만 똑같은 JWT 토큰이다
But, access token (접근 관여 토큰) / refresh token(재발급 관여 토큰)
Refresh Token적용 배경
단일 토큰 환경의 보안 문제
- 단일 토큰 사용 시 제 3자에게 토큰을 탈취 당하게 되면, 서버 입장에서는 해당 토큰을 무효화하기 어렵다
- 서버에서 보관이 가능한 토큰을 발급함으로써 서버측에서 토큰 탈취시 무효화를 할 수 있도록 컨트록 해야한다
-> Refresh token 활용
Refresh Token 사용시 장점
-
재로그인 유지 + 보안 강화 측면을 갖는 서비스 환경 구축이 가능하다.
- access Token이 짧은 유효 시간을 가지면 보안이 강화된다
- 하지만, 이러면 잦은 토큰 만료로 인해 빈번한 재로그인 서비스 환경이 구축된다
- 유효 기간이 짧은 access token과 유효 기간이 긴 refresh token을 사용함으로써 슬라이딩 세션 전략을 구현 가능하다
**참고 : 슬라이딩 세션이란?
- stateless 서비스에서 보안성을 위해 버려지는 편의성을 잡기 위한 세션 전략
- 서비스를 계속 사용하는 유저에게는 만료되기 전에 자동으로 만료 기한을 연장시켜주는 방법
-
토큰 탈취시 컨트롤 가능(보안 강화)
- refresh token도 탈취당할 위험이 언제나 존재
- refresh token은 access token과 달리 토큰을 발급 후 서버에서 저장
- 유효성을 확인하는 단계에서 서버 측의 저장된 refresh token과 요청에 담겨 넘어온 refresh token 정보를 비교하는 과정을 거친다
- refresh token이 탈취되었을 때에는 서버 측에서 저장된 토큰을 날려 무효화가 가능하기 때문에 access token이 탈취되었을 때와는 다른 상황
JWT 인증 순서(Access token, Refresh Token사용)
- 로그인 시, 서버는 로그인을 성공시키면서 클라이언트에게 Access Token과 Refresh Token을 동시에 발급한다.
- 서버는 DB(추후 redis사용)에 Refresh Token을 저장하고, 클라이언트는 Access Token과 Refresh Token을 쿠키와, 세션 혹은 웹스토리지에 저장하고 요청이 있을 떄마다 이둘을 헤더에 담아서 보낸다.
- 만료된 Access Token을 서버에 보내면, 서버는 JWT Token 내부의 Refresh Token과 DB(redis)에 있는 Refresh Token을 비교하여 일치하면 Access Token/Refresh Token을 재발급한다.
-> Refresh Token은 Access Token에 비해 만료기간이 길기때문에, Access Token이 만료되었을때 재발급해주는 열쇠의 역할을 한다.
Access Token/Refresh Token 재발급 원리
-
기본적으로 로그인 과정을 하면 Access Token과 Refresh Token을 모두 발급
-
사용자가 인증이 필요한 API에 접근하고자 하면, 가장 먼저 토큰을 검사
- case 1: Access Token과 Refresh Token이 모두 만료된 경우
-> 에러 발생(재로그인이 필요하며 둘다 재발급)
- case 2: Access Token은 만료되었지만, Refresh Token은 유효한 경우
-> refresh Token을 검증하여 Access Token을 재발급
- case 3: Access Token은 유효하지만, Refresh Token은 만료된 경우
-> Access Token을 검증하여 Refresh Tokend을 재발급?X -> 둘다 재발급
[내가 생각하기로는 Refresh Token의 취지랑 다른 것 같음->토큰 탈취시 컨트롤 기능 약화됨]
- case 4: Access Token과 Refresh Token이 모두 유효한 경우
-> 정상 처리
- 로그아웃을 하면 Access Token과 Refresh Token을 모두 만료시킴
Refresh Token 인증 과정
- 사용자 로그인(ID, Password)
- 서버에서 회원 DB에서 값을 비교
- 로그인 성공시 Access Token/Refresh Token 발급 후 DB에 Refresh Token 저장
- 클라이언트에 JWT(Access Token/Refresh Token)정보 전달
- 클라이언트는 JWT를 보관하고 있다가 요청시 헤더에 JWT를 담아서 요청을 보낸다.
- Access Token과 Refresh Token으로 검증
- 요청에 대한 응답 전송
- 시간이 지나서 Access Token가 만료됌
- 사용자는 이전과 동일하게 Access Token을 헤더에 담아 요청을 보냄
10.서버는 Access Token이 만료됨을 확인하고 권한이 없음을 보낸다.
(8 ~ 10 우리 프로젝트는 Access Token의 만료기간을 클라이언트에 던져줘서 만료시간이 지나면 Reissue 작업을 진행)
11.사용자는 Refresh과 Access Token을 함께 서버로 보냄
- 서버에서 받은 후 Access Token이 조작되지 않았는지 확인 한다.
- Refresh Token과 사용자의 DB에 저장된 Refresh Token을 비교 작업 진행
- Token이 동일하고 유효기간도 지나지 않았으면 새로운 Access Token을 발급해준다.
- 서버는 새로운 Access Token을 헤더에 담아 다시 API요청 응답을 진행한다.
참고 사이트)
https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-Access-Token-Refresh-Token-%EC%9B%90%EB%A6%AC-feat-JWT