Programming/TroubleShooting

회원가입 API 중복 요청 방지: Redis를 활용한 해결법

LazyCat 2024. 12. 9. 18:56
반응형

 

🤍 문제상황

회원가입 버튼을 두번 연속으로 눌렀다가, 쿼리가 두번 연속으로 날아가며 중복된 email값이 데이터베이스에 저장됨.

중복된 email 데이터로 인해 로그인 시 오류가 발생함

 

 

🤍 해결방법 : Redis

회원가입 비즈니스 로직이 실행되는 순간, 이메일이 Redis에 10분간 저장되도록 코드 추가

    public void signUp(SignupRequestDto signupRequestDTO){
        String email = signupRequestDTO.getEmail(); //이메일 중복검사
        isEmailDuplicate(email); //요청 중복 방지
        isRequestDuplicate(email); //비밀번호 암호화
        String password = passwordEncoder.encode(signupRequestDTO.getPassword());
        Member savedMember = Member.from(signupRequestDTO);
        savedMember.setPassword(password);
        memberRepository.save(savedMember);
    }

    public void isRequestDuplicate(String email) {
        if (redisUtil.hasKey(email)) throw new HomealoneException(ErrorCode.DUPLICATE_REQUEST);
        //레디스에 이메일 저장 (10초)
        redisUtil.set(email, "processing", 10000);
    }

 

이는 특정 요청이 일정 시간 내에 중복되지 않도록 처리를 한 것이다.

 

 

RedisUtil 코드 중 일부

    @Component
    @RequiredArgsConstructor
    public class RedisUtil {
        private final RedisTemplate<String, Object> redisTemplate;
        private final RedisTemplate<String, Object> redisBlackListTemplate;
        @Value("${spring.jwt.token.access-expiration-time}")
        private long expirationTime;
        
        .
        .
        .
        
        public void set(String key, Object value, long milliseconds) {
            redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(value.getClass()));
            redisTemplate.opsForValue().set(key, value, milliseconds, TimeUnit.MILLISECONDS);
        }
		
        public boolean hasKey(String key) {
            return redisTemplate.hasKey(key);
        }
        
}

 

 

 

반응형