본문 바로가기

분류 전체보기

(5)
redis의 keys 대신 scan을 사용하자 현재 개발중인 프로젝트에서는 로그인한 사용자에게 발급된 refreshToken을 저장하는 용도로 redis를 사용하고 있다.사용자가 로그인해 토큰을 발급받으면, redis에 다음과 같은 형태로 저장한다. key: refresh:{loginId}:{jti}value: {refreshToken} 만약 사용자가 비밀번호를 변경한다면, 보안상의 이유로 해당 사용자가 로그인한 전체 기기에서 로그아웃시켜야 한다.이를 해당 사용자의 모든 refreshToken을 삭제하고, jti를 blacklist에 등록하여 무효화하는 방식으로 구현하고자 했다. KEYS 명령처음에는 keys 명령으로 refresh:{loginId}:* 패턴에 부합하는 키를 조회해 처리하려 했다.하지만 이 방법에는 성능 문제점이 있다는 것을 발견했다..
StringRedisTemplate 사용 시에는 읽기 명령이 별도 커넥션에서 진행되지 않는다 최근 RedisTemplate을 사용하다, 트랜잭션 내에서 읽기 명령이 예상대로 동작하지 않는 문제를 겪었다.get이나 keys 같은 읽기 명령이 트랜잭션 안에서 정상적인 값을 반환하지 못했다. 이 문제는 StringRedisTemplate을 사용할 때 주로 발생했다.이는 StringRedisTemplate이 내부적으로 사용하는 DefaultStringRedisConnection 때문인데, 문제 발생 원인을 찾기까지 알아간 과정을 아래에 정리해 보려고 한다. 참고로 RedisTemplate을 직접 구성할 경우, 이런 문제가 회피될 수 있다.Spring Data Redis와 트랜잭션https://docs.spring.io/spring-data/redis/reference/redis/transactions...
Jackson 직렬화 시 getter에 부가적인 로직이 들어있다면 원래 필드값이 아닌 변경된 값이 직렬화될 수 있다. 문제 상황Redis를 사용하며 특정 객체를 캐싱하고자 했다.이 객체에는 민감한 데이터가 포함되어 있었고, 저장 시 해당 데이터를 암호화해 보안하고자 했다.그래서 처음에는 다음과 같이 설계했다.@NoArgsConstructor@AllArgsConstructorpublic class SecureData implements SecureInterface { private UUID id; private byte[] value; public static SecureData from(byte[] value) { return new SecureData( UUID.randomUUID(), EncryptionService.encrypt(value) ..
혹시 redisTemplate의 set을 잘못 호출하고 있지는 않나요 너무 어이없는 실수를 하고 오랜 시간을 낭비해서, 잊지 않기 위해 기록해두는 글.Redis에 같은 value의 값을 서로 다른 키로 저장하고자 했었다.TTL을 다르게 해서 관리하고 싶었기 때문이다. 하지만 분명히 같은 인스턴스를 value로 넣어주고 있음에도 꼭 다음과 같은 에러가 발생했다.Caused by: io.lettuce.core.RedisCommandExecutionException: ERR string exceeds maximum allowed size (proto-max-bulk-len) 원인을 모르고 한참을 헤매다가, redis-cli를 통해 실제 저장된 값을 확인해 보았다.하나의 키만 성공적으로 저장되어 있었다.다만 원래 저장되어야 할 값이 "hello"라고 하면, "\x00\x00\x..
Spring Security에서 AuthenticationProvider를 추가하니 로그인 인증이 실패하기 시작했다 결론부터 말하자면, 직접 구현한 AuthenticationProvider를 빈으로 등록해서다. 본래 필터 체인에 등록해 사용하던 Jwt 인증 필터는 Authorization 헤더에서 액세스 토큰을 얻고, 검증한 뒤 authentication 객체를 SecurityContextHolder에 등록하는 구조로 구성했었다. @Slf4j@Component@RequiredArgsConstructorpublic class JwtAuthenticationFilter extends OncePerRequestFilter { private final List WHITELIST = List.of( new AntPathRequestMatcher("/auth/login") ); private fina..