본문 바로가기
Refactoring/ReviewRanger

[리뷰레인저] DB에 불필요하게 쌓이는 RefreshToken을 해결하자 - 2

by 수짱수짱 2024. 4. 10.

해당 게시글은 프로젝트 '리뷰레인저'에 대해 개인 리팩토링 과정을 정리한 시리즈 글입니다.

이번 게시글의 주제는 '유효한 refreshToken뿐만 아니라 무효한 refreshToken까지 DB에 무의미하게 쌓이는 현상에 대한 개선안'입니다.


기존 로직의 문제점

RefreshToken이 불필요하게 DB에 주기적으로 저장되어 문제가 발생했다

지금은 local에서 테스트 한 환경이지만 refreshToken의 유효시간은 24시간으로 만약 사용자가 많아지고 24시간이 지난다면 이러한 불필요한 만료 토큰 데이터가 계속해서 쌓이게 될 것이다

그리고 위 데이터를 보면 알 수 있다싶이 refreshToken이 `user_id`를 가지고 있어야한다

그렇다면 차라리 user가 refreshToken을 가지고 있다면 어떨까?

 

해결 방안

RefreshToken을 따로 저장하는 것은 비효율적이다

그렇다면, User domain에 RefreshToken 필드를 만들고 User에 토큰 정보를 넣자!!

User의 RefreshToken은 처음엔 null이다가(@Nullable) 로그인 한 후 RefreshToken을 새로 갱신해주면 된다

이렇게 되면 User는 각 사용자마다 무조건 1개이므로 불필요한 RefreshToken이 DB에 쌓이지 않게된다

 

수정 후 코드

먼저 User domain에 refreshToken 필드를 추가해주고 refreshToken을 update할 수 있는 함수도 추가해준다.

이후 login 메소드에서 refreshToken을 저장하던 로직을 수정해준다

기존(주석 처리 된 코드)에는 refreshToken의 repository를 이용해서 토큰이 존재하는지 확인하고 생성할지 업데이트를 할 지 결정해야 했다

하지만 user domain에 필드로 refrehsToken이 생겼으니 user객체에 만들어진 refreshToken을 단순히 update 메소드의 인자로 넘겨주면 자동으로 update가 된다.

JwtTokenProvider getRefreshToken Method Update

refresToken을 얻던 로직도 단순화 되었다.

기존의 refreshToken repository에서 읽어오던 것을 JwtTokenProvider에 이미 주입 되어있는 userRepository 의존성을 이용하여 해당 user의 refreshToken을 가져올 수 있다.

RefreshToken Class Delete

 

RefreshTokenRepository Interface Delete

마지막으론 더 이상 사용하지 않는 refreshToken의 class와 repository를 삭제해주면 된다.

 

결과>

다른 아이디로 회원가입을 시도해도 refreshToken가 별도 DB에 쌓이지 않는 것을 확인할 수 있다

 

리팩토링 후기

처음에는 단순히 refreshToken에 대한 DB에 batch 시스템을 도입해 특정 시간마다 스케줄러가 데이터를 지우도록 하려고 했다

하지만, 이 방법은 문제가 많다. 예를 들어, 금방 로그인 한 유저의 refreshToken과 스케줄러의 시간이 겹쳐 유저의 refreshToken이 무효화가 될 수도 있다.

 

또한 refreshToken이 근본적으로 DB에 쌓여야 하는 이유는?에 대해 대답할 수 없었다.

이전의 refreshToken을 인증할 때엔 userId로 구분하여 인증했다. 즉, user table에 접근이 2차적으로 필요한 것이다.

그냥 처음부터 user가 refreshToken을 가지고 있게해서 table을 2번 거칠 필요없이 user table 1번만으로 인증하게 할 수 있다. 그러니, refreshToken이 근본적으로 별도의 table에 쌓여야 하는 이유는 없는 것이다.

물론, 만약 refreshToken에 저장되는 정보가 많다면 별도의 table로 빠지는게 맞지만 현재의 프로젝트에선 유저 id정보 외엔 별도의 데이터가 없기때문에 user table에 합치는 것이 적합함을 깨달았다.