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);
오늘의 결론
- Redis 직렬화 설정은 기본이지만 놓치기 쉬운 핵심 포인트다.
@JsonProperty는 DTO 매핑에서 중요한 역할을 하며, 필드명이 일치해도 명시해주는 게 안전하다.
- Redis 키 문자열 비교는 공백 여부까지도 정확하게 신경 써야 한다.
대단하십니다