프로젝트를 하던 도중 회원가입 과정에서 이메일 인증이 필요했다.
처음에는 SMTP 메일 전송을 구글로 하려고 하였다. 이를 위해서는 보안 수준이 낮은 앱의 액세스
를 허용해주어야 했다.
따라서 Google 계정으로 들어가 보안 수준이 낮은 앱의 액세스를 허용해주려고 하였는데
이러한 화면이 나왔다. 이 설정은 더 이상 사용할 수 없다는 안내문이 나와 이에 대해 알아보기 위하여 자세히 알아보기를 클릭하니
1달 조금 전부터 로그인 하도록 하는 것을 방지하고 있다는 내용이었다.
따라서 구글 대신 네이버를 사용하여 이메일 인증을 진행하려 한다.
네이버 메일의 좌측 하단의 환경 설정
을 누른다.
그러면 위와 같은 창이 뜨는데, 여기서 POP3/ IMAP 설정
탭에 들어간다.
그리고 위와 같이 POP3/SMTP 사용
을 누르고 위와 같이 설정을 시킨다.
설정을 저장하면 위와 같이 환경 설정 안내 화면이 밑에 작게 뜬다.
Gradle
implementation 'org.springframework.boot:spring-boot-starter-mail'
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
그리고 Config 파일을 추가한다.
application.yml
에 추가해도 되지만, 현재 진행하고 있는 프로젝트에서 Config 파일들을 관리하는 디렉터리가 있으므로 MailConfig.java
라는 파일을 만들어주었다.
@Configuration
public class MailConfig {
@Bean
public JavaMailSender javaMailService() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost("smtp.naver.com");
javaMailSender.setUsername("네이버 SMTP 설정 이메일");
javaMailSender.setPassword("네이버 계정 비밀번호");
javaMailSender.setPort(465);
javaMailSender.setJavaMailProperties(getMailProperties());
return javaMailSender;
}
private Properties getMailProperties() {
Properties properties = new Properties();
properties.setProperty("mail.transport.protocol", "smtp");
properties.setProperty("mail.smtp.auth", "true");
properties.setProperty("mail.smtp.starttls.enable", "true");
properties.setProperty("mail.debug", "true");
properties.setProperty("mail.smtp.ssl.trust","smtp.naver.com");
properties.setProperty("mail.smtp.ssl.enable","true");
return properties;
}
}
위의 내용들은
아까 설정해줬던 내용들을 그대로 옮기기만 하면 되는 것이다.
먼저 MailService.java를 작성하였다.
private MimeMessage createMessage(String code, String email) throws Exception{
MimeMessage message = javaMailSender.createMimeMessage();
message.addRecipients(Message.RecipientType.TO, email);
message.setSubject("오늘의 집 모의외주 프로젝트 인증 번호입니다.");
message.setText("이메일 인증코드: "+code);
message.setFrom(new InternetAddress(Secret.RECIPIENT));
return message;
}
public void sendMail(String code, String email) throws Exception{
try{
MimeMessage mimeMessage = createMessage(code, email);
javaMailSender.send(mimeMessage);
}catch (MailException mailException){
mailException.printStackTrace();
throw new IllegalAccessException();
}
}
public long sendCertificationMail(String email) throws BaseException {
if(userProvider.checkEmail(email) == 1){
throw new BaseException(BaseResponseStatus.DUPLICATED_EMAIL);
}
try{
String code = UUID.randomUUID().toString().substring(0, 6);
sendMail(code, email);
return mailDao.createVerificationCode(code, email);
}catch (Exception exception){
exception.printStackTrace();
throw new BaseException(BaseResponseStatus.DATABASE_ERROR);
}
}
createMessage
라는 함수로 메일로 보낼 내용들을 생성한다. 그후 sendMail
메서드를 이용하여 실제로 이메일을 보낸다.
위 코드는 인증 코드 보내기
에 사용된 메서드들이다. UUID를 사용하여 인증 코드를 발생시켰고, 해당 코드를 사용자에게 전송해주는 코드이다.
그리고 컨트롤러에서 메일을 보낼 예정이다.
@ResponseBody
@PostMapping("")
public BaseResponse<Long> sendEmail(@RequestBody String data) throws BaseException{
JSONObject parser = new JSONObject(data);
String email = parser.getString("email");
if(email == null){
return new BaseResponse<>(BaseResponseStatus.POST_USERS_EMPTY_EMAIL);
}
if(!ValidationRegex.isRegexEmail(email)){
return new BaseResponse<>(BaseResponseStatus.POST_USERS_INVALID_EMAIL);
}
try{
mailService.sendCertificationMail(email);
long verifyCodeId = mailService.sendCertificationMail(email);
return new BaseResponse<Long>(verifyCodeId);
}
catch (BaseException baseException){
return new BaseResponse<>(baseException.getStatus());
}
}
JSON 형태로 데이터를 받는 과정에서 JSON 파싱을 통해 원하는 정보인 이메일을 추출한 뒤, 메일을 보내도록 하는 코드이다.
인증번호 조회를 위해 DB에 정보가 업데이트 되므로 POST
메서드를 사용하였다.
이 코드들을 실행시키면
원하는 코드들을 제대로 받을 수 있다.
BaseException은 직접 만든 Exception 일까요?