[TIL]2025.04.23

기 원·2025년 4월 23일

TIL - 2025.04.23

오늘 배운 것 개요

  • RefreshToken Redis 저장 실패 이슈 원인 분석 및 해결
  • @RequestBody 바인딩 실패 원인 분석
  • Redis 키 문자열 공백 문제 해결
  • 정확한 Redis 직렬화 설정 방법 학습

1. RefreshToken Redis 저장 실패 트러블슈팅

1. 문제 상황

  • 로그인 시 RefreshToken을 Redis에 저장하고, 이후 이를 통해 AccessToken을 재발급받는 구조를 설계함.
  • /reissue API 호출 시 다음과 같은 예외 발생:
java.lang.IllegalArgumentException: RefreshToken이 비여 있거나, null입니다.

2. 원인 분석

1) Redis 저장 여부 확인

127.0.0.1:6379> keys *
1) "RefreshToken"
2) "BlackList"
3) "testKey"
127.0.0.1:6379> get RT:1
(nil)
  • 예상했던 RT:1 키가 존재하지 않거나 null로 조회됨.
  • LoginService 내부 확인 결과, Redis 저장 로직이 빠져 있었음.

2) 저장 로직 추가 후에도 이상한 직렬화 결과 발생

1) "\xac\xed\x00\x05t\x00\x04RT:1"
  • 이는 Java 기본 직렬화 방식으로 저장된 결과. 사람이 읽을 수 없음.

3. 해결 방법

Redis 직렬화 설정 추가

StringRedisSerializer stringSerializer = new StringRedisSerializer();
template.setKeySerializer(stringSerializer);
template.setValueSerializer(stringSerializer);
template.setHashKeySerializer(stringSerializer);
template.setHashValueSerializer(stringSerializer);
template.afterPropertiesSet();

정상 저장 확인

127.0.0.1:6379> keys *
1) "RT:1"
2) "BlackList"
3) "RefreshToken"
127.0.0.1:6379> get RT:1
"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxI..."

2. RefreshToken 재발급 과정에서 바인딩 실패

1. 문제 상황

  • Redis에는 잘 저장되었지만, /reissue 요청 시 다음 예외 발생:
java.lang.IllegalArgumentException: RefreshToken이 비여 있거나, null입니다.

2. 원인 분석

  • TokenRefreshRequest DTO가 다음과 같이 구성되어 있었음:
@Getter
@NoArgsConstructor
public class TokenRefreshRequest {
    private String refreshToken;
}
  • 하지만 바인딩이 실패하여 값이 null로 전달됨.

3. 해결 방법

@Getter
@NoArgsConstructor
public class TokenRefreshRequest {

    @JsonProperty("refreshToken")
    private String refreshToken;
}
  • @JsonProperty를 명시하여 JSON 필드와 정확하게 매핑되도록 수정함.

3. Redis 키 비교 오류

1. 문제 상황

  • 다음과 같은 예외 발생:
java.lang.IllegalArgumentException: 서버에 저장된 RefreshToken 과 다릅니다.

2. 원인 분석

String storedToken = redisTemplate.opsForValue().get("RT: " + userId);
  • Redis에는 "RT:1"로 저장되어 있었고, 코드에는 "RT: 1"처럼 공백이 포함된 상태로 조회하고 있었음.

3. 해결 방법

redisTemplate.opsForValue().get("RT:" + userId);
  • 공백 제거하여 일치하도록 수정

오늘의 결론

  1. Redis 직렬화 설정은 기본이지만 놓치기 쉬운 핵심 포인트다.
  2. @JsonProperty는 DTO 매핑에서 중요한 역할을 하며, 필드명이 일치해도 명시해주는 게 안전하다.
  3. Redis 키 문자열 비교는 공백 여부까지도 정확하게 신경 써야 한다.

profile
노력하고 있다니까요?

1개의 댓글

comment-user-thumbnail
2025년 4월 24일

대단하십니다

답글 달기