RefrethToken저장 방식에 대한 고민
정리
1. AccessToken이 탈취될 위험성이 있기 때문에 만료기간 줄임 -> 유지시간 짧아짐(사용자 편의성 낮아짐)
2. RefreshToken도입 -> 유지시간보완
3. RefreshToken 또한 탈취될 가능성이 존재 -> RTR(Refresh Token Rotate)를 이용한 탈취 감지
RTR을 구현하는데에 두 가지 방식이 있지만 저는 확장성을 위해 RT : PK방식을 선택했습니다.
탈취 감지를 해서 처리를 하더라도 완벽한 보안은 불가능합니다. 다만 예방할 수 있는 부분은 최대한 고려하자는 취지에서 고민해보았습니다.
PK : RefreshToken방식 | RefreshToken : PK방식 | ||||
장점 | - 사용자의 로그인 정보가 하나임을 보장함 -> RT만 만료시킨다면 모든 토큰을 무효화할 수 있음 - 탈취 감지( 요청한 토큰과 서버의 토큰이 다를 때 ) |
- 다중 환경 이용 가능 - 탈취 감지( 서버에 없는 토큰으로 재발급 요청했을 때 ) |
|||
단점 | 다중 환경에서의 로그인 불가 (2PC, 웹 앱 등 ) |
RT의 재사용은 막을 수 있지만 AT 탈취는 막을 수 없음 |
일반적인 JWT 동작 로직
일반적으로 JWT를 이용한 인증/인가를 구현할 때 AccessToken의 탈취에 대한 대처로 RefreshToken을 사용합니다.
방법은 AT의 유효기간을 짧게 가져가고 만료 시 RT을 이용해 AT를 재발급 하는 방식입니다.
RefreshToken 탈취 감지
첫 번째 방법 - PK : RefreshToken
Email : RefreshToken의 형식으로 사용하는 방식입니다.( 사용자의 Unique Key로 RT는 하나임을 보장 )
위 방법을 도입했을 때 얻어갈 수 있는 기능은 다음과 같습니다.
1. 유저의 로그인 여부를 체크할 수 있음(RT의 존재여부)
2. 탈취 감지
-> 사용자보다 토큰을 탈취한 침입자가 먼저 서버의 RT를 갱신했다면?
-> 사용자가 접근했을 때 RT값이 다름(탈취로 감지 RT제거)
-> 모든 사용자는 다시 로그인해야함
3. 로그아웃 기능 처리
-> RT만 제거하면 모든 토큰은 무효화 시킬 수 있음
실제 구현했던 인증 흐름
PK : RT방식의 문제점
기본적으로 RT가 하나임을 보장한다는 전제하에 구현한 로직들이기에
-> 다른 환경에서의 로그인이 불가능합니다.(서로 다른 컴퓨터 or 웹, 앱간 동시 로그인이 불가)
두 번째 방법 - RefreshToken : PK (RTR)
첫 번째 방법이 확장성이 너무 떨어졌기에 다시 생각하게된 방법입니다.
RTR방식은 재발급 요청 시 기존의 RT를 만료시키고 새로운 RT와 AT를 발급하는 방식입니다.
-> 즉, AT가 만료됐을 시점부터 매번 1회용 RT를 사용해서 재발급
첫 번째 방법과 마찬가지로 RT가 두 번 이상 사용됐을 때(해당 방법에서는 RT가 서버에 없을 때) 탈취 감지 가능
탈취 된 것을 감지했다면 사용자의 모든 RT를 만료시키면 됩니다.