본문 바로가기

Spring Security

[Spring Security] Redis에 refreshToken 저장 시 공백 이슈

redisTemplate을 이용하여 리프레시 토큰을 저장 할 때, 이상하게 토큰 값 앞에 공백이 왕창 박혀서

들어온 토큰 값이랑 redis에 저장된 토큰 값이랑 비교가 안되었던 오류가 발생하였다.

 

인코딩, 디코딩 문제인줄 알았으나 확인 결과 아니었고,

임시로 trim()으로 문자열을 비교해 테스트 코드를 통과시키긴 했지만 찝찝했다.

 

다시 시간을 두고 살펴본 결과 redisTemplate의 ValueOperations의 set 메소드가 다양한 오버로딩을 지원하고 있었고,

세번째 인수 타입에 의한 이슈였다.

 

public RefreshToken save(RefreshToken refreshToken) {
        redisTemplate
                .opsForValue()
                .set(
                        String.valueOf(refreshToken.getUserId()),
                        refreshToken.getRefreshToken(),
                        refreshToken.getExpiration());
        return refreshToken;
}

 

원래 저장하는 메서드에서는 세번째 인수로

RefreshToken 객체에서 만료시간을 long타입 필드로 갖고있기 때문에, long타입을 전달했었다.

 

다만, set메소드를 잘 살펴보면

default void set(K key, V value, Duration timeout) {

		Assert.notNull(timeout, "Timeout must not be null");

		if (TimeoutUtils.hasMillis(timeout)) {
			set(key, value, timeout.toMillis(), TimeUnit.MILLISECONDS);
		} else {
			set(key, value, timeout.getSeconds(), TimeUnit.SECONDS);
		}
}

void set(K key, V value, long offset);

 

나는 위의 메서드를 사용하고 싶었지만,

아래의 메서드가 사용되어 offset으로 적용되어서 그만큼의 공백이 생긴 채 redis에 저장된 것으로 추정된다.

 

public RefreshToken save(RefreshToken refreshToken) {
        redisTemplate
                .opsForValue()
                .set(
                        String.valueOf(refreshToken.getUserId()),
                        refreshToken.getRefreshToken(),
                        Duration.ofSeconds(refreshToken.getExpiration()));
        return refreshToken;
}

 

알맞은 Duration 객체 타입으로 인수를 전달했더니 해결되었다.