오늘은 어제 정리한 JWT에 이어 Refresh Token에 대해 정리했다.
단순한 형태의 JWT 토큰만 사용한다면 아래와 같은 딜레마가 발생한다.
토큰 기한이 짧을경우 사용자에게 잦은 로그아웃 경험을 주어 불편해진다.
토큰 기한이 길 경우 한번 발급한 토큰에 대해서는 서버가 제어권을 가질 수 없기 때문에 탈취되었을 경우 위험성이 커진다.
위와같은 문제 때문에 JWT 구현에 있어서는 주로 Access Token과 Refresh Token으로 나누어 사용한다.
클라이언트의 정보를 담은 토큰. 실제 인증 과정에서 사용된다.
새로운 Access Token을 재발급하기 위해 사용되는 토큰
목적
Access Token의 기한을 짧게 만들어 자주 재발급하도록 해 보안을 강화하면서도, 사용자에게 잦은 로그인 경험은 주지 않기 위함이다.
일반적으로는 Refresh Token은 2주, Access Token은 30분 이내 정도로 설정한다고 한다.
물론, Refresh Token도 탈취위험에서 자유롭지는 않다.
클라이언트가 첫 로그인 시 Access Token과 Refresh Token을 서버에서 함께 발급한다. 이때 서버에서는 Refresh Token을 회원 DB에 저장해두고, 클라이언트는 안전한 저장소에 Refresh Token을 저장한다.
이후 인증 과정에서 클라이언트는 Access Token만 요청으로 보낸다.
Access Token이 만료되면 서버 혹은 클라이언트에서 만료기간을 확인 후 Refresh Token을 서버로 보낸다. 서버에서는 회원 DB에 있는 Refresh Token과 비교 후 일치하면 새로 Access Token을 발급해 준다.
JWT
Refresh Token을 똑같이 JWT로 저장해 둔다면 stateless의 특성을 그대로 갖기 때문에, DB에 별도 엑세스가 필요없다는 장점이 있으나 Refresh Token 자체를 탈취 당하면 무효화 시킬 수 없어 기존 JWT의 단점이 그대로 남게된다.
Random String or UUID
랜덤한 문자열이나 UUID를 사용한다면 회원 DB에 따로 이 정보를 저장하고 Access Token 만료시 DB를 이용해 확인해야 한다. 하지만 문제가 발생 하거나 Refresh Token이 탈취당하면 사용자를 강제로 로그아웃시키거나 토큰을 바꿀 수 있다는 장점이 있다.
RTR (Refresh Token Rotation)
Refresh Token을 이용해 Access Token을 새로 발급 받을 시 Refresh Token도 만료시키고 새롭게 발급하는 방법이다. 주기적으로 Refresh Token도 갱신되므로 보안을 한층 더 강화할 수 있다.