회원 가입 시에 사용자 신원 확인 및 중복 가입 방지를 위해 이메일 인증을 도입하였다.
사용자가 회원가입란에 이메일을 입력하고 인증 번호 전송 버튼을 누른다.
SpringBoot의 이메일 전송 인터페이스 JavaMailSender를 사용하여 구글 SMTP서버에 이메일 전송을 요청, 사용자 이메일에 인증코드를 발송할 수 있도록 구현하였다. JavaMailSender를 이용하면 간단하게 제목, 발신자, 내용 등을 설정하여 이메일을 생성할 수 있다. 또한, send 메서드를 통해 간단하게 이메일을 발송할 수 있다.
@Bean
public JavaMailSender javaMailSender(){
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
Properties properties = new Properties();
properties.put("mail.transport.protocol", protocol);
properties.put("mail.smtp.auth", auth);
properties.put("mail.smtp.starttls.enable", starttls);
properties.put("mail.smtp.debug", debug);
mailSender.setHost(host);
mailSender.setUsername(username);
mailSender.setPassword(password);
mailSender.setPort(port);
mailSender.setJavaMailProperties(properties);
mailSender.setDefaultEncoding(encoding);
return mailSender;
}
MimeMessageHelper를 사용하게 되면 보다 더 간단하게 이메일을 생성할 수 있다. MimeMessage는 이메일의 여러 부분(제목, 발신자, 수신자 등)을 다루는 객체로 MimeMessageHelper를 이용하여 보다 간소화된 설정이 가능하다.
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(sender, "Celebrem"); // 발신자
helper.setTo(recipient.getEmail()); // 수신자
helper.setSubject("Celebrem 회원 가입 인증 코드가 발송되었습니다."); // 내용
String templateContent = readTemplateContent(templateFileName);
templateContent = templateContent.replace("{{ePw}}", code);
helper.setText(templateContent, true);
javaMailSender.send(message);
RDB에 이메일, 인증번호 쌍을 저장하는 만큼 만료된 인증번호를 자동으로 삭제할 필요성이 있었다. 물론, 사용자가 정상적으로 이메일 인증을 완료하였을 경우에는 DB에서 삭제가 되도록 했다. 하지만 비정상적인 경우(인증번호 미전송, 사용자의 실수로 인한 중복 클릭)의 경우 DB에 계속해서 남아있게 된다. 이를 해결하기 위해 2가지 사항을 고려해보았다.
만료된 이메일 인증코드를 DB에서 지우기 위한 것만으로 Redis를 적용하는 것은 굳이? 라는 생각이 들었다. 새로운 기술 스택을 적용하는 것에는 항상 side-effect를 고려해야 하는데 Redis를 사용함으로써 얻을 수 있는 이득 보다는 메모리 사용량 증가 측면이 더 부각되어 보이기에 스케줄러를 이용하여 일정 시간마다 만료된 인증코드를 삭제하는 방식을 선택했다.