목차

1. 도입 이유
사실 이전 refresh Token은 DB에 저장해서 인증 시에 반환하는 용도로 썼다.
여기서 드는 의문이 우리가 세션 로그인 대신 JWT를 도입하는 이유는 무상태성 + 서버의 부담을 줄이고 싶다는 이유이다.
그런데 refresh Token을 DB에 저장하게 된다면 이러한 장점이 없어지지 않을까?..
찾아 본 결과
1. 무상태성 유지
DB에 저장하는건 사실 무상태성이 깨지는 것은 아니다.
무상태성이 깨지는 경우는 클라이언트에 대한 상태를 유지하는 경우이다. 즉 db 자체에 refresh Token을 저장한다고 깨지지 않음!
즉 무상태성을 유지할 수 있음
2.서버의 부담
db에 접근 하는 것이이 서버쪽 부담이 될 것이라고 생각하지만 리프레시라는 동작은 굉장히 드물게 일어나는 일이라 큰 부담이 되지 않음

(우리의 경우 14일로 설정 해놓았다)
조금 생기는 부담보다 refresh토큰을 이용한 보안적인 측면이 훨씬 이득일 것 같다.
3. 확장 시 유리
사실 나는 mrd프로젝트를 MSA로 전환하는 과정을 한 번 시도해보고 싶다.
실제로 대규모 트래픽 및 분산 환경을 운영하는 경험을 가지면서 어떤 부분을 고민해야 하고, 어떤 선택을 해야 하는 지를 다 겪어보고 싶다
그 의미의 첫번 째로 redis 서버를 둬서 분산 서버 관리를 해보고 싶은 이유가 가장 크다.
2. 레디스
Redis는 Remote Dictionary Server의 약자로, 오픈 소스 기반의 인메모리 데이터 저장소입니다. 키-값 구조를 기반으로 데이터를 저장하고 관리하며, 데이터베이스, 캐시, 메시지 브로커 등 다양한 용도로 사용됩니다.
(레디스에 관해서는 전에 쓴 포스팅 참고)
redis(1) - 자료구조 활용
redisRedis (Remote Dictionary Server) 개요고성능의 키-값(key-value) 저장소로, 거대한 맵(Map) 데이터 저장소형태를 가지고 데이터를 메모리에 저장하여 빠른 읽기와 쓰기를 지원주로 캐싱, 인증 관리, DB동
ernest45.tistory.com
redis(2) - pub & sub
redis pub sub 기능redis를 활용하여 메시지를 발행하고 구독하는 서비스특징Redis Pub/Sub 시스템에서 동일한 채널을 여러 구독자가 구독하면, 해당 채널로 발행된 메시지가 모든 구독자에게 발송한번
ernest45.tistory.com
3. redis 사용 시 고려 사항들
3-1 redis 의존성 및 yml 추가

Lettuce vs jedis
Spring Data Redis에서 사용할 수 있는 Redis Client 구현체는 Lettuce와 Jedis가 있다
spring-boot-starter-data-redis를 사용하면 의존성 설정 없이 Lettuce를 사용할 수 있음
Jedis는 별도의 설정이 필요하다.
그리고 결과적으로 성능도 좋음
Lettuce가 코드도 간단하고 레퍼런스도 많기에 Lettuce를 사용
https://jojoldu.tistory.com/418
Jedis 보다 Lettuce 를 쓰자
Java의 Redis Client는 크게 2가지가 있습니다. Jedis Lettuce 둘 모두 몇천개의 Star를 가질만큼 유명한 오픈소스입니다. 이번 시간에는 둘 중 어떤것을 사용해야할지에 대해 성능 테스트 결과를 공유하
jojoldu.tistory.com
자세한 성능비교 사이트이다.

3-2 repository vs redisTemplate
Redis Repo vs Redis Template
1. Repository
Repository 인터페이스를 정의하는 방법은 Spring Data JPA를 사용하는 것과 비슷
Redis는 많은 자료구조를 지원하는데, Repository는 Hash 자료구조로 한정하여 사용이 가능함
Repository를 사용하면 객체를 Redis의 Hash 자료구조로 직렬화하여 스토리지에 저장!
2. Redis Template
Redis Template은 Reids 서버에 커맨드를 수행하기 위한 고수준의 추상화를 제공한다.
결론!
CrudRepository를 상속받는 RedisRepository 방식으로 사용할 것이다
별도의 Configuration 의존성 추가가 필요하지 않고 Redis Template 방식보다 훨씬 구현이 간편하고
내가 쓸 용도는 hash를 사용한 Key:value (리프레쉬토큰:ID)로만 이용할 생각이기에
4. RefreshTokenRedis
package me.hanjun.domain;
import lombok.Getter;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
@Getter
@RedisHash(value = "refreshTokenRedis", timeToLive = 14440)
public class RefreshTokenRedis {
@Id
private String refreshTokenRedis;
private Long userId;
public RefreshTokenRedis(String refreshTokenRedis, Long userId) {
this.refreshTokenRedis = refreshTokenRedis;
this.userId = userId;
}
}

4-1 @ID
JPA의 ID가 아닌 data,annotation.id를 import 해야함(Jpa에 저장하지 않기에 의존성 필요 x)
java.persistence.id가 아닌 opg.springframework.data.annotation.Id 를 import해야 됩니다.
Refresh Token은 Redis에 저장하기 때문에 JPA 의존성이 필요하지 않습니다. (persistence로 하면 에러납니다.)
@RedisHash 어노테이션은 Redis Lettuce를 사용하기 위해 작성해야 됩니다.
value는 redis key 값으로 사용됩니다.
redis 저장소의 key로는 {value}:{@Id 어노테이션을 붙여준 값}이 저장됩니다.
제가 작성한 value는 refreshToken이고, @Id 어노테이션이 붙어있는 값을 test 라고 넣는다고 가정하겠습니다.
"refreshToken:test"와 같이 저장됨을 알 수 있습니다.
4-2 @RedisHash
@RedisHash는 Redis Lettuce를 사용하기 위함
RedisHash의 value로 적은 값이 key로 적용! (에너테이션의 밸류가 레디스의 키로 저장된단 뜻임)
즉 현재로 redis에는 토큰값:id로 저장된다.
timeToAlive
timeToLive는 유효시간을 값으로 초 단위로 설정함
14400은 4시간이다. 원래는 14일로 했지만 간단한 테스트를 하기 위해서!
기존 14일인 (1209600으로 바꿔놓음)
5 RefreshTokenRedisRepo
package me.hanjun.repository;
import me.hanjun.domain.RefreshTokenRedis;
import org.springframework.data.repository.CrudRepository;
public interface RefreshTokenRedisRepository extends CrudRepository<RefreshTokenRedis,String> {
}

원래의 jpaRepo가 아닌 Crud를 상속해야 한다!
6 리프레쉬 토큰 저장 및 생성 로직

기존의 refresh 토큰은 db에 저장하기 때문에 받은 id와 tokenProvider에 만들어진 String refreshToken은
refreshToken이라는 entity에 없으면 새로 만들어서 저장 or 있으면 업데이트 하는 형식으로 만들어진다.
----로 그어 놓은 점선 윗 부분의 코드!
하지만 새로 만든 refreshTokenRedi는 redis에 저장하기에 redisRepo에 저장하는 코드이다.
6-1 refreshToken이 필요한 경우

refresh토큰이 필요한 경우에는 클라이언트 쿠키에 저장해준 refreshToken을 token api로 서버에다 담아서
accessToken을 요청한다.

원래는 db에서 그 refresh 토큰에 맞는 userId를 반환해줬지만,
이젠 redis를 refresh토큰을 키 값으로 value인 id를 가져온다!
7 redis 서버 확인
docker를 이용해서 redis 서버를 띄운 후 확인해보자!


도커로 실행한 redis로 접속한 모습!
7-1. ttl 확인

잘 저장된 걸 볼 수 있다!

ttl도 설정한 대로 잘 뜨는 모습이다~!

로그인도 성공!
'프로젝트' 카테고리의 다른 글
| My Record - 다중 SecurityFilterChain 우선 순위 : 트러블 슈팅 (0) | 2025.04.18 |
|---|---|
| My Record - OAuth2 카카오 도전기! 리팩토링2 (0) | 2025.04.16 |
| My Record - OAuth2 카카오 도전기! 리팩토링 1편 (0) | 2025.04.14 |
| My Record 만들기 -에러 처리 가이드 (0) | 2025.04.09 |
| My Record - 토큰 만료 시 401 처리 (0) | 2025.04.08 |