Kuma's Curious Paradise
[이룸] 240130 refresh token 왜 필요한가? 본문
🔥 구현해야 하는 부분은 ‘회원가입’과 ‘로그인’ 기능입니다.
지금까지 token 하나에 만료 시간을 부여해 사용했지만,
이번에는 refresh token을 사용해 보려 합니다. 왜 이런 결정을 내리게 되었을까요?
Access token과 Refresh token, 왜 필요한가?
- 먼저, jwt 토큰은 유저의 신원이나 권한을 결정하는 정보를 담고 있는 데이터 조각입니다. 이러한 jwt 토큰을 탈취당했을 때, 서버는 이 사실을 알 수 없다는 것이 큰 문제입니다. 따라서 서버는 토큰에 ‘유효 기간’을 설정하여 일정 시간이 지나면 토큰이 효력을 상실하게 만듭니다. 탈취자가 계속해서 서버를 망가트릴 수 없게 하기 위함이지요.
- 토큰 유효 기간이 지나면 유저는 자동으로 로그아웃 됩니다. 만약 이 유효기간이 짧다면 유저는 사이트를 탐색하다가도, 글을 쓰다가도 계속해서 로그인해야 할 것입니다. 그렇다고 유효기간이 길면 보안상 좋지 않습니다.
- 이 문제를 해결하기 위해 jwt 토큰 2개를 발급하는 방법이 생겨났습니다. 바로 access token 과 refresh token을 두는 것입니다.
Refresh token이란 무엇인가?
- 처음 로그인을 완료했을 때, access token과 refresh token이 함께 발급됩니다. refresh token 은 긴 유효 기간을 지니면서(마이크로소프트의 경우 1년), access token이 만료되었을 때 새로 발급하도록 해 주는 열쇠가 됩니다.
- 예를 들어, access token의 유효 기간은 1시간, refresh token의 유효 기간은 2주라고 해 봅시다. 사용자가 서버와 소통하다가 1시간이 지나게 되면, access token이 만료됩니다. 이때 refresh token이 만료되지 않은 상태라면, 사용자는 access token을 새롭게 발급받을 수 있습니다. 다시 말해, access token이 만료되어 갱신이 필요할 때 refresh token을 사용합니다.
- refresh token의 유효기간이 지났다면, 사용자는 새로 로그인을 해야 합니다. 보통 2주의 유효 기간을 가지며, refresh token 또한 탈취될 가능성이 있기 때문에 적절한 유효 기간을 설정하는 것이 중요합니다.
그림으로 이해하기
출처: https://tansfil.tistory.com/59
과정 이해하기
- 로그인 인증에 성공한 클라이언트는 Refresh Token과 Access Token 두 개를 서버로부터 받습니다.
- 클라이언트는 Refresh Token과 Access Token을 로컬에 저장합니다.
- 클라이언트는 헤더에 Access Token을 넣고 API 통신합니다. (Authorization)
- 일정 기간이 지나 Access Token의 유효기간이 만료되었다면 4.1. Access Token은 이제 유효하지 않으므로 권한이 없는 사용자가 됩니다. 4.2. 클라이언트로부터 유효기간이 지난 Access Token을 받은 서버는 401 (Unauthorized) 에러 코드로 응답합니다. 4.3. 401를 통해 클라이언트는 invalid_token (유효기간이 만료되었음)을 알 수 있습니다.
- 헤더에 Access Token 대신 Refresh Token을 넣어 API를 재요청합니다.
- Refresh Token으로 사용자의 권한을 확인한 서버는 응답쿼리 헤더에 새로운 Access Token을 넣어 응답합니다.
- 만약 Refresh Token도 만료되었다면 서버는 동일하게 401 error code를 보내고, 클라이언트는 재로그인해야 합니다.
JWT 토큰의 구조와 보안
- jwt 토큰은 header, payload, signature로 되어 있습니다.
- Header: 토큰 타입 + 서명 알고리즘 일반적으로 토큰 타입은 “JWT”로 설정되며, 서명 알고리즘은 HMAC SHA256, RSA 등이 있습니다.
- Payload: 발급자 + 토큰 주체 + 유효 기간 + 발급 시간 + 토큰 수신자 / 공개 클레임 + 비공개 클레임
- Signature : 헤더와 페이로드의 인코딩된 문자열과 서버에서만 알고 있는 비밀키를 사용하여 생성됩니다. 토큰이 변경되지 않았음을 검증하는 데 사용합니다.
- 토큰의 유효 기간은 payload에 적혀 있고, signature는 header와 payload의 내용을 비밀키로 암호화한 것입니다. 따라서 탈취자가 payload의 유효 기간을 바꾼다고 해서 signature가 바뀌지는 않기 때문에, 서버는 이것이 탈취되거나 malformed된 토큰임을 알 수 있고 접근 권한을 내어 주지 않을 수 있습니다.
- 즉 access token 의 유효 기간이 짧기 때문에 서버는 보안적으로 유리한 위치를 점합니다.
Refresh token은 탈취에서 안전할까?
- refresh token은 통신 빈도가 적기는 하지만 완전히 탈취 위험에서 안전하지는 않습니다. refresh token이 탈취당할 경우, 탈취자는 refresh token이 만료될 때까지 자유롭게 access token을 신청할 수 있습니다.
- 따라서 refresh token 탈취를 예방하기 위해 OAuth 에서는 Refresh Token Rotation이라는 방법을 제시합니다.
Refresh Token Rotation 이란?
- Refresh Token Rotation(RTR)은 Access Token이 만료될 때마다 Refresh Token도 함께 교체하는 방식을 말합니다. 즉, refresh token의 유효 기간을 짧게 만들면서 재사용이 불가능하게 만들어 보안을 보장하는 방법입니다.
- 로그인 성공 시, 클라이언트는 AT1과 RT1을 발급받습니다. AT1이 만료되면, AT2를 발급받기 위해 RT1을 사용합니다. 서버는 클라이언트에게 AT2와 새로운 RT2를 발급합니다. 만약 탈취자가 RT1을 탈취하여 AT2를 발급받으려고 하면, RT 재사용이 감지되어 해당 Token Family는 아예 사용할 수 없게 됩니다. 이러한 방법으로, refresh token이 탈취되더라도 보안 위험이 감소합니다.
토큰과 관련하여 꼭 생각해 봐야 할 지점
💡 SECURITY / CONVENIENCE / PRIVACY
아무리 보안을 위한 일이라도 유저가 계속해서 로그인해야 하는 불평한 상황이 생긴다면 유저는 서비스를 이용하지 않을 것입니다. 그렇다고 해서 보안이 약하고 개인 프라이버시가 노출되는 상황은 없어야겠지요. 따라서 토큰을 발급하는 자는 AT와 RT를 적절히 사용하고 유효 기간을 적정히 부여하여 보안과 편의성, 프라이버시를 모두 잡을 수 있도록 해야 합니다.
'이룸 프로젝트' 카테고리의 다른 글
[이룸] 240202 CORS 에러 이해하기 (1) | 2024.03.06 |
---|---|
[이룸] 240201 카카오 로그인 도입 이유 (0) | 2024.03.06 |
[이룸] 240131 API 명세 및 ERD 작성에 대한 회고 (0) | 2024.03.06 |
[이룸] 240129 API 명세 작성에 대한 회고 (0) | 2024.03.06 |
[이룸] 240127 프로젝트 시작 회고 (0) | 2024.03.06 |