SY 개발일지
article thumbnail

프로젝트를 진행하며 RefreshToken을 과연 어디에 저장을 해야 효율적인가에 대해 고민을 하게 되었습니다.

 

이전의 프로젝트에서는 단순히 MySQL 데이터베이스에 저장을 하였습니다.

그래서 만료일과 액세스 토큰, 그리고 리프레스 토큰값을 저장해둔 후 액세스 토큰이 만료가 되었을 시, 액세스 토큰값과 리프레스 토큰값을 이용하여 재발급 로직을 실행하였습니다.

 

하지만, 이렇게하면 데이터베이스에 쓰레기 데이터가 너무 많이 남는다는 단점과 사용자의 액세스 토큰이 만료가 될 때마다 데이터베이스에 접근해야 한다는 단점이 있습니다. 그만큼 사용자가 많아질수록 데이터베이스에 접근을 많이하여 성능도 좋지 않겠죠.

 

그래서 많은 사람들이 사용하는 Redis를 이용하여 RefreshToken을 저장하는 것을 생각하게 되었습니다.

 

(해당 포스트에는 단순하게 spring boot 와 redis를 연결하여 사용하는 방법에 대해서만 작성되어있습니다.

자세한 사용법은 다른 분들이 작성하신 블로그글을 보시는 것을 추천드립니다.)

 

Redis 란

레디스(Redis)는 메모리 기반의 데이터 저장소이다. 키-밸류(key-value) 데이터 구조에 기반한 다양한 형태의 자료 구조를 제공하며, 데이터들을 저장할 수 있는 저장소이다. 최신 버전의 레디스는 PUB/SUB 형태의 기능을 제공하여 메세지를 전달할 수 있다. 즉, 데이터 저장 뿐만 아니라 다양한 목적으로 사용할 수 있다.레디스는 메모리에 데이터를 저장하기 때문에 저장 공간에 제약이 있어, 주로 보조 데이터 저장소로 사용한다. 이를 극복하기 위해 레디스 클러스터 기능을 제공하고 있어 저장 공간을 확장할 수 있다. 또한 저장된 데이터를 영구적으로 디스크에 저장할 수 있는 백업 기능을 제공하므로 애플리케이션의 주 저장소로도 사용할 수 있다. 또한 메모리에 데이터를 저장하기 때문에 빠른 처리 속도가 장점이다. 레디스 내부에서 명령어를 처리하는 부분은 싱글 스레드 아키텍처로 구현되어 있다. 멀티 스레드 아키텍처보다 구조가 단단하게 설계되어 여러 장점이 있다. 
- “스프링 부트로 개발하는 MSA 컴포넌트 - 김병부“

 

즉, 단순히 말해 빠른 처리 속도를 가진 키-밸류 데이터 구조에 기반한 메모리 기반의 데이터 저장소입니다.

 

Redis 설치하기 (mac)

저는 현재 맥북을 사용하고 있기 때문에 맥 기준으로 적어보도록 하겠습니다.

brew install redis

 

다음은 레디스를 시작/중지하는 명령어들입니다.

# redis 시작
brew services start redis

# redis 중지
brew services stop redis

# redis 재시작
brew services restart redis

# redis cli 사용
redis-cli

 

실행한 후 brew services info redis를 이용하여 실행 상태를 확인할 수 있습니다.

 

Spring Boot 에 redis 연결

레디스를 설치했으니 이제 Spring boot 프로젝트와 redis를 연결해보도록 하겠습니다.

 

build.gradle 의존성 추가

implementation 'org.springframework.boot:spring-boot-starter-data-redis'

 

application.yml에 redis 추가

기본적으로 설정되는 redis의 포트번호는 6379 입니다. 

spring:
  data:
     redis:
    	host: localhost
        port: 6379

 

Redis Configuration 생성

@Configuration
@EnableRedisRepositories
public class RedisConfig {

    @Value("${spring.data.redis.host}")
    private String host;
    @Value("${spring.data.redis.port}")
    private int port;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(host, port);
    }

    @Bean(name = "customRedisTemplate")
    public RedisTemplate<?, ?> redisTemplate() {
        RedisTemplate<?, ?> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        redisTemplate.setEnableTransactionSupport(true);

        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());

        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        return redisTemplate;
    }

}

 

Repository 사용

Redis는 Repository를 사용하는 방법과 레디스 템플릿을 사용하는 방법이 있습니다.

저는 저에게  더욱 익숙한 Repository를 사용해보도록 하겠습니다.

 

1️⃣ RefreshToken

@RedisHash를 이용하여 Redis에서 사용함을 명시합니다.

@Builder
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@RedisHash(value = "refresh_token")
public class RefreshToken {

    @Id
    private String authId; // id

    private String accessToken; // 액세스 토큰

    @Indexed
    private String refreshToken; // 리프레시 토큰

    @TimeToLive
    private long expiredAt; // 만료일

}
@Id (key) 값이 되며, refresh_token:{id} 위치에 auto-increment 된다.
@RedisHash 설정한 값을 Redis의 key 값 prefix로 사용한다.
@Indexed 값으로 검색을 할 시에 추가한다.
@TimeToLive 만료시간을 설정(초(second) 단위)

 

2️⃣ RefreshTokenRepository

mysql에서 JpaRepository를 사용하는 것처럼, CrudRepository 인터페이스를 상속받습니다.

@Id또는 @Indexed 어노테이션을 적용한 프로퍼티들만 CrudRepository가 제공하는 findBy ~ 구문을 사용할 수 있습니다.

public interface RefreshTokenRepository extends CrudRepository<RefreshToken, String> {

    Optional<RefreshToken> findByRefreshToken(String refreshToken);
    Optional<RefreshToken> findByAuthId(String authId);
    
}

 

 

참고

- https://velog.io/@hkyo96/Spring-RedisTemplate-Serializer-%EC%84%A4%EC%A0%95

- https://developer-nyong.tistory.com/21#article-2--redisrepository-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

 

[Spring Boot, Database] Spring Boot + Redis 제대로 활용하기(2)

저번 포스팅에서는 레디스라는 데이터베이스 자체에 대해서 자세히 알아보았다. 이번 포스팅에서는 스프링 부트에서 레디스를 사용하는 법을 알아보자. Spring Boot에서 레디스 설정하기 스프링

developer-nyong.tistory.com

 

profile

SY 개발일지

@SY 키키

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!