Project

[Project] Redis(Elasticache Redis)로 RefreshToken을 관리하기

woo0doo 2023. 11. 25. 12:47

서론

팅클(Tincle)이라는 프로젝트에서 JWT를 통해 프론트와 소통을 했는데, 이 프로젝트는 친구기반 SNS 서비스입니다. 만약 사용하게 된다면 한번 접속할 때 '짧은 시간이 아닌 긴 시간동안 머무르지 않을까?' 판단했습니다. 때문에 토큰 재발급하는 횟수가 많다고 생각했습니다. 그에 따른 시간 비용을 줄이고자 Redis로 RefreshToken을 관리한 경험을 얘기하려 합니다.


데이터베이스가 있는데 왜 Redis를 사용할까?

Redis는 인메모리 캐시로 메모리에서 데이터를 처리합니다. Client가 필요로 하는 정보가 만약 DB에 존재하게 된다면 Disk 영역까지 가야하기 때문에 시간이 오래 걸리게 됩니다. 반면 Redis에 정보가 존재하게 된다면 Memory 영역에서 처리 후, 값을 반환하게 되어 시간이 단축될 것입니다.


EC2에 Redis 설치 VS AWS Elasticache Redis

Redis를 사용하기로 마음을 먹고 어떻게 사용할지 조사 중에, 두가지 방법이 있다는 것을 알았습니다. EC2에 Redis를 설치하는 방법과, Elasticache Redis라는 AWS에서 지원하는 Redis가 있었습니다.

EC2에 직접 Redis를 설치하는 것의 장점은 비용이 있습니다. Elasticache Redis는 프리티어가 아니라면 돈을 지불해야하는데, EC2에 설치하게 되면 비용을 지불하지 않아 장점이 있습니다. 유사한 예를 들면 EC2에 RDS를 사용하지 않고 DB를 설치하는 것이라고 생각하면 될 것 같습니다.

 

Elasticache Redis의 장점으로는 아래 그림과 같이 Scale Out에 자유롭고, EC2가 인스턴스를 재시작해도 Redis 값이 존재하다는 것입니다. Elasticache Redis는 유료이지만 프리티어에게는 1년간 무료로 제공하고 있습니다.

저는 제 프로젝트의 Spec이 프리티어여서 EC2에 최대한 부담을 주지 않는 방향으로 개발하고 싶었습니다. 또한 Elasticache도 무료로 1년간 사용할 수 있었기 때문에 AWS Elasticache Redis로 사용하기로 결정했습니다.


Redis는 무조건 좋은 건가요? + 위험성

Redis는 아까 언급했듯이 인메모리 캐시입니다. 이 말은 즉슨 휘발성 성질을 가지고 있습니다. 비정상적으로 종료되게 된다면 DB처럼 값이 저장이 되어있지 않고, 값이 사라지게 됩니다. 이 위험성 때문에 비정상적으로 종료될 확률이 적은 AWS Elasticache Redis를 사용을 결정하게 된 것도 있습니다. 이 휘발성 성질을 고려해서 Redis에 저장하는 정보는 신중하게 결정해야 합니다. Redis가 빠르다고 해서 중요한 정보들을 Redis에 저장하게 된다면, 값이 많아질수록 Redis의 부담도 커질 것이고 비정상적으로 종료가 된다면 많은 데이터들을 유실하게 될 것입니다. 

모든 것들을 고려해서 저는 Redis에 RefreshToken을 저장하기로 생각했습니다.

 

왜?

만약 Redis의 값이 모두 유실되었다고 생각하면 모든 유저의 RefreshToken이 사라지게 될 것입니다.. 그럼 유저들에게 끼치는 악영향은 무엇이 있을까요? 소셜 로그인을 다시 하는 번거로움이 전부입니다. 어플에 큰 악영향이라고 생각하지 않아서 괜찮다고 판단해서 도입하게 되었습니다.


바뀐 흐름

Client로부터 RefreshToken 받기 -> Disk 영역으로 진입 -> MySQL의 RefreshToken 테이블에 저장된 값과 요청 들어온 refreshToken 값과 비교 후, 일치하면 토큰 발급

 

Client로부터 RefreshToken 받기 -> Redis에서 값 비교 후, 일치하면 토큰 발급


프로젝트에 사용된 Java/Spring 코드로 보기 :

토큰 발급 : https://github.com/DoDream-dev/Tinqle-Server/blob/develop/src/main/java/tinqle/tinqleServer/config/jwt/JwtProvider.java

Redis 설정 : https://github.com/DoDream-dev/Tinqle-Server/blob/develop/src/main/java/tinqle/tinqleServer/config/redis/RedisConfig.java

Redis 동작: https://github.com/DoDream-dev/Tinqle-Server/blob/develop/src/main/java/tinqle/tinqleServer/config/redis/RedisService.java