redis 와 refreshToken

개발하는 구황작물·2023년 2월 8일
0

개인 프로젝트

목록 보기
6/9

메인 플젝 중 refresh token을 저장하기위해 Redis를 활용하기로 하였다.
굳이 refreshToken을 DB에 저장하지 않고 redis를 사용하는 이유는
1. redis 특유의 빠른 액서스 속도,
2. 기한이 정해져 있는 token을 db에 저장했다가 지우기보단 redis에다가 데이터 유효기간을 설정하여 관리하는 것이 나을 것 같아서 이다.

다음은 소스 코드이다

Gradle에 추가

implementation 'org.springframework.boot:spring-boot-starter-data-redis:2.3.1.RELEASE' // 추가

application.yml에 redis 포트번호 추가

spring:
	redis:
    	host: localhost
    	port: 6379

RefreshToken Entity 추가

@Getter
@AllArgsConstructor
public class RefreshToken {
    @Id
    private String refreshToken;

    private Long usersId;
}

Redis를 사용하는 방법에는 두가지가 있다. Repository 인터페이스를 정의하거나 Redis Template를 사용하는 방법이다.(redisRepository는 트랜잭션을 지원하지 않는다고 한다.)
필자는 Redis Template를 사용하였다.

RedisConfig 추가

@Configuration
public class RedisConfig {
    private final String redisHost;
    private final int redisPort;

    public RedisConfig(@Value("${spring.redis.host}") String redisHost,
                       @Value("${spring.redis.port}") int redisPort) {
        this.redisHost = redisHost;
        this.redisPort = redisPort;
    }

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(redisHost, redisPort);
    }

    @Bean
    public RedisTemplate<?, ?> redisTemplate() {
        RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return  redisTemplate;
    }
}

refreshTokenRepository

@Repository
public class RefreshTokenRepository {
    private final RedisTemplate redisTemplate;

    public RefreshTokenRepository(final RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void save(final RefreshToken refreshToken) {
        ValueOperations<String, Long> valueOperations = redisTemplate.opsForValue();
        valueOperations.set(refreshToken.getRefreshToken(), refreshToken.getUsersId());
        redisTemplate.expire(refreshToken.getRefreshToken(), 60L, TimeUnit.SECONDS);
    }

    public Optional<RefreshToken> findById(final String refreshToken) {
        ValueOperations<String, Long> valueOperations = redisTemplate.opsForValue();
        Long usersId = valueOperations.get(refreshToken);

        if(Objects.isNull(usersId)) {
            return Optional.empty();
        }
        return Optional.of(new RefreshToken(refreshToken, usersId));
    }
}
profile
어쩌다보니 개발하게 된 구황작물

0개의 댓글