본문 바로가기

개발

[SpringBoot] 이메일 인증 구현

목표: 회원가입할 때 유저가 작성한 이메일에 인증코드를 전송하고 redis에 그 코드를 저장해 입력된 코드와 비교한다.

 

 

 

이메일 인증코드를 redis에 저장하여 비교하는 방식 or 토큰을 포함한 링크를 전송해 사용자가 해당 링크를 클릭했을 때 토큰이 일치하면 완료 처리하는 방식을 할지 고민하다 전자를 선택했다.. 다음에는 후자 방식으로 해봐야겠다..!

 

 

1. 해당 이메일 인증 코드 전송하기 

 

 

build.gradle

/*SMTP*/
	implementation 'org.springframework.boot:spring-boot-starter-mail'

 

application.yml

spring:	
  mail:
    host: smtp.gmail.com
    port: 587
    username: ming67244@gmail.com
    password: // 구글에서 받은 비밀번호
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true

 

MailService

@Service
@RequiredArgsConstructor
public class MailService {
    @Autowired
    private JavaMailSender javaMailSender;
    public boolean sendEmail(String email){

        Random random = new Random();
        int randomValue = random.nextInt(9000) + 1000;

        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setTo(email);
        simpleMailMessage.setSubject("인증 메일");
        simpleMailMessage.setText("인증번호: " + randomValue);
        try{
            javaMailSender.send(simpleMailMessage);
            return true;
        } catch (Exception e){
            return false;
        }
    }

 

MailController

@RestController
@RequiredArgsConstructor
public class MailController {
    private final MailService mailService;
    @PostMapping("/api/send")
    public ResponseEntity<Boolean> send(@RequestParam String email){
        return new ResponseEntity<>(mailService.sendEmail(email), HttpStatus.OK);
    }
}

 

테스트

 


2. Redis에 인증번호 저장

 

Mail

@Getter @Setter
@RedisHash("mail")
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Mail {
    @Id
    @JsonIgnore
    private String id;

    private Integer code;

    @TimeToLive(unit= TimeUnit.SECONDS)
    private Integer expiration;
}

보통 테이블에서는 @Setter를 사용하지않는데 여기서는 모두 set이 필요해서 사용했다.

 

 

 

MailRepository

public interface MailRepository extends CrudRepository<Mail, String> {
}

 

MailService - send

javaMailSender.send(simpleMailMessage);
            Mail mail = mailRepository.save(
                    Mail.builder()
                            .id(email)
                            .code(randomValue)
                            .expiration(300) // 300 = 60 * 5 (5분)
                            .build()
            );

기존에 만들었던 sendEmail 함수에 Mail을 생성하고 저장하는 코드를 추가했다.

 

 

MailService - verifyCode

    public boolean verifyCode(VerifyRequest verifyRequest) throws Exception {
        Mail mail = mailRepository.findById(verifyRequest.getEmail()).get();
        if(mail.getCode().equals(verifyRequest.getCode())){
            return true;
        }
        return false;
    }

 

MailController

 @GetMapping("/email/verify")
    public ResponseEntity<Boolean> verify(@RequestBody VerifyRequest verifyRequest) throws Exception {
        return new ResponseEntity<>(mailService.verifyCode(verifyRequest), HttpStatus.OK);
    }

 

테스트

인증코드를 전송하면 이메일(키)-인증코드(값)으로 redis에 저장된다.


+Swagger

이메일 스웨거 정리완료!