본문 바로가기
DB/Redis

TIL 230905 : Redis 3 - [Refactor] 기존 인증번호 DB를 Redis로 옮기기.

by 우인입니다 2023. 9. 8.

Redis를 활용해 RefreshToken을 구현해봤다.
엄밀히, 따지면 Redis없이도 가능했었는데 사용한 이유가 뭘까?
데이터를 쓰는 기간이 만료기간이 없고 유실의 리스크가 크지않고, 빠르게 처리하기 위함이었다.

이번에는 기존에 회원가입 이메일 인증번호를 MySQL DB에 저장해둔 것을 Redis로 옮겨보려 한다.
이 또한 5분이라는 만료시간이 있고 이후에는 바로 삭제해주는 것이 좋기에 활용하기 적절하다고 판단했다.

 

이메일 인증번호 기존코드

Controller

@PostMapping("/users/mail-confirm")
ResponseEntity<ApiResponseDto> mailConfirm(...) throws Exception {
    userService.sendMailAndCreateVerificationCode(requestDto); //인증번호 생성 및 메일 발송 메소드
    return //성공 메시지;
}

UserController에 해당 API를 추가해두었다.

회원가입 페이지 내에서 '인증번호 발송' 버튼을 누를 때 호출 되는 API이다.

 

 

Service

인증번호 전송

@Transactional
public void sendMailAndCreateVerificationCode(MailRequestDto requestDto) throws Exception {
        String email = requestDto.getEmail();

        // 회원 중복 확인
        checkEmail(email);

    	// 인증번호 생성 후 메일 전송 메소드
        String code = mailService.sendMessage(email);
        
        // 생성된 인증번호와 유저정보로 VerificationCode 객체 생성
        VerificationCode verificationCode = new VerificationCode(email, code);
        
        // 생성된 객체 DB에 저장
        verificationCodeRepository.save(verificationCode); // 이 부분을 Redis로 변경해야한다.
    }

해당 서비스 메소드를 보면 아래와 같다.

 

1. 유저정보에서 이메일 주소를 가져온다. + 중복이메일 확인

2. 인증번호를 발송해준다. + 인증코드를 가져온다.

3. 인증번호 정보 객체에 어떤 유저가 어떤 인증번호를 받았는 지를 담아 생성한다.

4. DB에 저장해둔다. + 이후 확인 API를 통해 확인할 때 조회 된다.

 

메일로 온 인증번호
DB에 저장된 인증번호와 이메일 주소. 확인을 위한 boolean값.

 

인증번호 확인

@Transactional
public void verifyCode(VerificationRequestDto verificationRequestDto) {
    String email = verificationRequestDto.getEmail();
    String code = verificationRequestDto.getVerificationCode();

    //가져온 정보로 DB조회하고 있는 지 체크.
    VerificationCode verificationCode = verificationCodeRepository.findByEmailAndCode(email, code)
            .orElse(null);

    // 인증코드 검증하는 코드
    ...
}

다시 저장해둔 DB를 조회해서 해당정보가 있는지 체크를 한다.

 

 

Redis로 변경

 

회원가입 인증번호 과정에 대한 설명은 생략하고 이때 기존에 MySQL에 담았던 것을 Redis로 바꾸는 방향으로 수정하려 한다.

 

VerificationCodeRepository

import com.sparta.lafesta.user.entity.VerificationCode;
import org.springframework.data.repository.CrudRepository;

public interface VerificationCodeRepository extends CrudRepository<VerificationCode, String> {
}

 : CrudRepository를 상속

 

 

 

VerificationCode

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@RedisHash(value = "Verification-Code", timeToLive = 3 * 60) //3분
public class VerificationCode {
    @Id
    @Column(nullable = false, unique = true)
    private String email;

    @Column(nullable = false, unique = true)
    private String code;

    public VerificationCode(String email, String code) {
        this.email = email;
        this.code = code;
    }
}

 : email을 키값으로 갖고 객체 정보를 value로 갖게 설정했다.

    뭔가 여기서는 value로 객체가 아닌 code만 가지고 있어도 될 것 같은데, 설정하는 법을 모르겠다.

 

 

인증번호 생성 및 전송 메소드

String code = mailService.sendMessage(email);
VerificationCode verificationCode = new VerificationCode(email, code);
verificationCodeRepository.save(verificationCode);

전송된 인증번호를 받아 Redis에 담아줄 객체를 생성해 저장해준다.

 

 

인증번호 검증 및 인증완료 정보 저장

@Transactional
public void verifyCode(VerificationRequestDto verificationRequestDto) {
	//인증요청 정보 가져오기
    String email = verificationRequestDto.getEmail();
    String code = verificationRequestDto.getVerificationCode();

	//인증 코드 DB에서 가져오기
    VerificationCode verificationCode = verificationCodeRepository.findById(email)
            .orElse(null);

	//인증 코드 검증
    ...(Redis에서 가져온 코드랑 입력한 코드가 맞는 지 검사)

	//인증 성공 후 인증완료 정보 저장
    verificationConfirmRepository.save(new VerificationConfirm(email, true));
}

 

VerificationConfirm : 인증정보 저장 객체

 :repository는 같은 방식으로 생성

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@RedisHash(value = "SignUp-Confirm", timeToLive = 30 * 60) //30분
public class VerificationConfirm {
    @Id
    private String email;
    private boolean confirm;
}

 

 

 

 

Postman 테스트

인증번호 Redis에 저장 확인

 

유료시간 3분으로 설정

유효시간도 확인.

 

 

인증을 완료 했다.

 

 

인증이 완료 되면 인증을 완료했다라는 인증정보(SignUp-Confirm)을 30분간 보관하고 있는다.

이 정보를 회원가입 요청시에 체크하게 되는 데 그때 사용된다.

 

 

완료 후 삭제된 인증 정보

 

 


더 공부할 것

Redis에서 정보를 가져오는 방법 중 CrudRepository를 상속받아 사용중인 데, 이 때 쿼리 메소드를 사용하는 방법(findByIdAndCode 등)과 CrudRepository와 RedisTemplate 둘의 장단점과 언제 쓰면 좋을 지