Spring Boot + Redis + Jwt
기존에 Spring Security + Jwt 를 사용해서 만든 웹서비스에 RefreshToken 을 사용하기 위해 Redis 를 사용해보았다.

로그인에 성공하면 AccessToken, RefreshToken 을 발급한다. 이떼 RefreshToken은 Redis 를 통해 인메모리에 유저 ID 값을 키값으로 잡아 Token 값과 같이 저장하였다.
각 서비스를 이용할때 해당 AccessToken 을 사용해 인증, 인가를 진행한다.
AccessToken 만료 시 RefreshToken 을 체크해서 유효하다면 AccessToken을 발급한다. 허나 RefreshToekn 도 만료라면 SecurityContextHolder에 Authentication 을 set 하지 않고 인증 인가를 허가 하지 않는다.
RefreshToken

Spring Data Redis 에서 Redis 를 사용하는 방법은 크게 2가지 방법이 있다.
RedisTemplate 와 Redis Repository 이다.
필자는 후자인 RedisRepository 를 사용하였다. 두 방식 모두 사용전에 Redis 와연결 설정을 해야하는데 Redis 에서는 기본적으로 localhost 에 연결해주기 때문에 따로 설정없이 진행하였다.
마치 JPA Repository 설정하는것과 유사하다. 이렇게 설정하고 token을 조회할땐 @id 값에 해당하는 값을 통해 JPA 와 동일한 메서드를 통해 가져올수있다. 저장 역시 JPA 와 동일하게 save 메서드를 사용하면 된다.

RefreshToken을 저장하면 해당 내용처럼 저장되어진다.
AccessToken의 유효기간은 짧게 RefreshToken은 다소 길게 잡아서 AccessToken 탈취 위험성을 낮춘다.
또한 RefreshToken 의 긴 유효기간에 대비해서 RefreshToken Rotation 방법을 사용했다.
AccessToken 재 발급시 RefreshToken 도 재발급 하는 방식으로 RefreshToken 의 긴 유효기간에서 발생하는 취약점을 보완하였다.
다만 Logout 시 AccessToken의 만료 기간이 아직 남아있다면 서비스에 접근이 가능하지 않나 라는 의문이 생겼다.
그래서 로그아웃 시 AccessToken의 유효기간이 남아있다면 로그아웃 후 에도 서비스 접근이 가능하다는 점에서 위 같은 BlackList 등록 같은 로직을 사용했다.
그러나tateLess 함을 유지하지 못햇다는 점에서 아쉬움 이 남는다.
정리
RefreshToken을 사용 함으로써 기존 AccessToken 만을 사용하였을때의 토큰 탈취 위험성을 낮출수있었다. 문제가 생기면 RefreshToken 을 삭제 시키면 되기에 Logout 기능도 구현하였다.
요새는 많은 회사들이 클라우드 서비스를 사용하는데 주로 스케일 아웃 방식을 선호한다고 알고있다.
Stateless 한 방식을 사용하는 이유에는 해당 방식이 스케일 아웃 방식에 Fit 한 방식이라는 점을 빼놓을수 없을거같다.
Last updated