이번엔 프로젝트에 필요한 이메일 인증 기능( 학교 이메일로 인증 번호를 전송하는 기능 )을 구현해보려 한다.
이번 글에선 여러 smtp서버가 있지만 다음을 이용해보려 한다.
간단하게 플로우를 살펴보면
사용자의 이메일 인증 요청 -> 서버에서 이를 토대로 연결된 SMTP서버에 목적지 이메일 주소로 메일 전달 요청 -> 서버(스프링 부트)에 연결된 SMTP서버에서 목적지 SMTP서버로 메일을 전송한다 -> 사용자가 메일을 확인한 후 올바른 인증 코드를 서버에 다시 제출한다
원리는 꽤 단순하니 바로 구현을 해보자
SMTP설정
메일의 환경설정에 들어가 POP3/SMTP사용을 활성화 한다 (IMAP도 상관없다..)
그러면 하단에 pop3서버 및 포트번호 등 기타 정보를 알려준다.
gradle의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-mail'
MailConfig작성
package com.example.emptySaver.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import java.util.Properties;
@Configuration
public class MailConfig {
@Bean
public JavaMailSender javaMailSender(){
JavaMailSenderImpl javaMailSender=new JavaMailSenderImpl();
javaMailSender.setHost("smtp.daum.net");
javaMailSender.setUsername("아이디입력");
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.daum.net");
properties.setProperty("mail.smtp.ssl.enable","true");
return properties;
}
}
해당 smtp서버의 주소,아이디,비밀번호,포트를 입력해준다.
또한, 설정파일을 따로 만들어서 사용해도 되지만 여기선 config내에서 만들어 바로 사용했다.
property 이름들이 꽤 직관적이니 따로 설명은 하지 않겠다.
컨트롤러 작성(이메일 전송)
@PostMapping("/sendEmail")
public ResponseEntity<String> sendEmail(@RequestParam String email){
log.info("email : "+email);
String code = mailService.sendMessage(email);
return new ResponseEntity<>(code,null,HttpStatus.OK);
}
가볍게 이메일을 받아 해당 이메일로 인증코드를 보내고 클라이언트에게도 인증코드를 보내는 컨트롤러이다.
서비스 작성(이메일 전송 서비스)
package com.example.emptySaver.service;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
@Service
@Slf4j
public class MailService{
@Autowired
JavaMailSender sender;
private MimeMessage createMessage(String target, String code) throws MessagingException, UnsupportedEncodingException {
MimeMessage message = sender.createMimeMessage();
message.addRecipients(Message.RecipientType.TO,target);
message.setSubject("이메일 인증 코드입니다.");
String detail="";
detail += "<div style='margin:100px;'>";
detail += "<h1> 안녕하세요</h1>";
detail += "<h1> XX에서 보냅니다~~.</h1>";
detail += "<br>";
detail += "<p>아래 코드를 복사하여 앱에서 입력해주세요<p>";
detail += "<br>";
detail += "<br>";
detail += "<div align='center' style='border:1px solid black; font-family:verdana';>";
detail += "<h3 style='color:blue;'>인증 코드입니다.</h3>";
detail += "<div style='font-size:130%'>";
detail += "CODE : <strong>";
detail += code + "</strong><div><br/> "; // 메일에 인증번호 넣기
detail += "</div>";
message.setText(detail, "utf-8", "html");
message.setFrom(new InternetAddress("전송자주소@daum.net","보내는 사람 이름"));
return message;
}
private String createCode(){
String s = UUID.randomUUID().toString();
return s.substring(0,Math.min(8,s.length()));
}
public String sendMessage(String target){
String code = createCode();
try {
MimeMessage message = createMessage(target, code);
sender.send(message);
}catch (Exception e){
log.error("메일 전송 오류 발생");
//TODO : 추후 예외 통합 처리 할 때 여기서 오류 넘겨줘야 함
throw new RuntimeException();
}
return code;
}
}
먼저 createMessage의 경우 DI받은 JavaMailSender로 MimeMessage를 만들어내는 메소드다.
로직의 경우 addRecipients로 이메일을 보낼 대상(target)을 추가하고
setSubject로 이메일 제목을 설정하며
detail적인 부분(이메일 내용)을 작성하여 setText로 설정한다.
setFrom으로 발신지 정보 (이메일주소, 발신자이름)을 설정한다.
다음으로 createCode는 말그대로 인증코드를 만드는 함수다. UUID를 사용했다.
이 두 메소드를 이용해서 컨트롤러에서 호출하는 sendMessage는 인증 코드를 만들고 메세지를 만들어 sender.send를 통해 메세지(이메일)을 전송한다. (예외처리를 제대로 하지 않았는데, 기능 구현을 조금 더 하고 controller advice를 이용해서 통합 예외 처리를 할 예정이다.)
이제 필요한건 다 구현했다.
직접 postman으로 호출해보면
인증코드가 잘 오고
메일로도 잘 전송되는걸 확인할 수 있다.
생각보다 이메일 인증기능이 구현하기 쉬워 좀 당황했지만 여튼 프로젝트에 큰 차질이 없을 것 같다는 생각이 들어 기분은 좋았다.
참고
https://terianp.tistory.com/119
https://limjunho.github.io/2022/08/08/EmailAuthentication.html
'Spring' 카테고리의 다른 글
웹소캣이란? (0) | 2023.05.04 |
---|---|
spring boot v3에 스웨거 적용하기 (0) | 2023.04.18 |
Spring Batch (0) | 2023.04.05 |
ExceptionHandling (0) | 2023.04.05 |
Spring Security - Cors. setAllowCredentials (0) | 2023.04.05 |