Stateless한 JWT는 안전한 로그아웃을 구현할 수 없다
JWT 방식으로 발급한 토큰의 제어권은 서버가 가지고 있지 않다.
구조적으로 생각해보면 당연한 이야기이다.
JWT를 사용하는 장점이 Stateless함을 바탕으로 빠른 인증 처리인데, 그 과정에서 서버는
해당 토큰이 유효한지 만을 체크하기 때문에, 서버에선 해당 토큰에 대한 정보가 아무것도 없다.
따라서 토큰이 탈취당한 경우 다음과 같은 상황이 발생한다.
사용자A = 토큰의 주인
해커 = 사용자 A의 토큰 탈취자
사용자 A가 서버에 로그인 요청
서버 : 보자.. 토큰이 유효하네? 패스~
해커가 사용자 A의 토큰으로 로그인 요청
서버: 보자.. 토큰이 유효하네? 패스~
이런 상황은 JWT 토큰의 유효시간을 줄이면 그나마 좀 방지가 될 것 같다.
토큰이 탈취되자마자 사용한다면 어쩔 수 없지만, 조금의 시간이 지난 후 사용한다면 만료되었을테니 말이다.
그런데 이 방식도 문제점이 있다.
자동 로그인, 로그인 유지같은 사용자 편의를 위해서라면, 토큰의 유효 시간이 길어야한다.
토큰의 유효시간을 5분으로 해버리면 사용자가 로그인 하고 5분만 자리를 비워도 로그인을 다시 해야되는 것이다.
따라서 서버에서 토큰의 유효 시간을 정하기란 애매하다.
짧게 하자니 사용자 편의성이 떨어지고
길게 하자니 보안 위험이 커진다.
사용자 편의성과 보안을 모두 챙기는 방법은 없을까?
이러한 상황에 도입된 개념이 바로 Refresh Token이다.
Refresh Token을 사용하면 보안과 사용자 편의성을 모두 해결할 수 있다.
설명을 위해 용어를 간단히 정리하자면,
Access Token : 권한 인증을 위한 토큰
Refresh Token : Access Token의 재발급에 관여하는 토큰
Refresh Token의 형태
Refresh Token은 두 가지 방법으로 구현될 수 있다.
- JWT
- Access Token처럼 stateless한 JWT 방식으로 구현하는 방법
장점 : stateless하다. 따라서 별도의 DB 조회를 하지 않아도 돼서 서버 부하가 적다.
단점 : stateless하다. 위 예시와 마찬가지로 Refresh Token이 탈취당하면 무효화 방법이 없다.
- Access Token처럼 stateless한 JWT 방식으로 구현하는 방법
- JWT가 아닌 형태
- 랜덤한 문자열이나 UUID를 사용하는 방법
장점 : 사용자를 강제로 로그아웃 시키거나, 차단할 수 있고, Refresh Toekn 탈취 시 즉각적인 대응이 가능
단점 : 문자열을 사용자 정보와 매핑되도록 DB에 저장해야 하므로 Refresh Token 사용마다 DB 조회를 해야한다
- 랜덤한 문자열이나 UUID를 사용하는 방법
JWT 방식의 Refresh Token과 Access Token의 작동 흐름은 다음과 같다.
- 사용자가 로그인 성공 시 Refresh Token과 Access Token을 모두 발급한다.
- Access Token이 만료되면 다음 순서를 통해 토큰이 재발급 된다.
- 클라이언트로부터 Refresh Token을 전달 받는다.
- Refresh 토큰의 다음 세 조건을 확인한다.
- 토큰의 type이 RTK
- 토큰의 URI가 /account/reissue
- 토큰에 담긴 정보가 * Redis 인 메모리(In Memory)에 존재
- 세 조건이 만족되면 새로운 AccessToken을 발급하여 응답한다.
Refresh Token을 이용한 로그아웃 구현
사용자가 로그아웃을 하면 Access Token을 재발급 하던 Refresh Token이 더 이상 토큰을 재발급 하지 말아야 한다.
stateless한 Refresh Token의 사용을 막기 위해 블랙리스트 DB 테이블을 도입하자.
블랙리스트를 이용한 재발급 거부 흐름은 다음과 같다.
- 로그아웃된 RTK를 블랙리스트 DB에 보관한다.
- ATK가 만료되어 재발급 API가 호출되면 요청한 RTK가 블랙리스트에 있는 지 확인한다.
- 블랙리스트에 존재한다면, 발급을 거부한다
이 방법을 사용하면 로그아웃 이후에 Access Token이 탈취당하더라도
Access Token의 유효기간이 굉장히 짧아 사용하기 어렵게 만들 수 있다.
Refresh Token의 장단점
블랙리스트에 DB에 접근해야 하므로 일부 stateful 해지는 단점이 있지만,
로그인 성공 및 로그인 유지 상태에서는 기존의 stateless한 장점을 살릴 수 있다.
출처
'개발 지식' 카테고리의 다른 글
JWT(JSON Web Token) 구성 요소 (0) | 2024.02.24 |
---|