안녕하세요 오늘은 Spring Boot에서 메일을 발송하는 방법에 대해서 포스팅하도록 하겠습니다. 현재 투다에는 메일로 비밀번호 찾기 기능을 제공하고 있는데, 이 부분을 Spring Boot에서 어떤 식으로 구현할 지 알아보도록 하겠습니다.
먼저 메일이 어떤 방식으로 발송되는지 동작 원리에 대해 간단하게 알아보겠습니다. A가 B에게 메일을 전송할 때
의 방식으로 동작합니다. SMTP 프로토콜은 HTTP와 유사하게 데이터 전송 시 클라이언트처럼 동작하고, 데이터를 수신 시 서버처럼 동작합니다. HTTP와의 차이점은 SMTP의 경우 한글이나 binary 데이터 처럼 ASCII가 아닌 문자를 포함한다면 반드시 이 메시지는 전송되기 전에 7bit ASCII로 인코딩이 되어야 합니다.
추가적으로 user agent에서 메시지를 가져오는 방식은 SMTP 프로토콜로 사용하지 않습니다. SMTP 프로토콜은 푸시용 프로토콜이기 때문에 POP3, IMAP 등의 메일 접속 프로토콜을 이용하여 메일을 가져옵니다.
// Mail
implementation "org.springframework.boot:spring-boot-starter-mail"
그럼 지금부터 Spring Boot에서 메일 기능을 구현해보겠습니다. 우선 build.gradle에 다음과 같은 dependency를 추가해줍니다.
#Mail
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username={이메일 주소}
spring.mail.password={구글 2단계 인증 앱 비밀번호}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
이번 테스트는 587 포트 SMTP 프로토콜을 통해 gmail을 이용하여 메일을 전송해보도록 하겠습니다. gmail의 경우 메일을 발송하는 방법은 크게 2가지 입니다. 우선 첫 번째로 계정의 보안 수준을 낮춰 외부에서 접근 가능하도록 하는 방법이 있고, 두 번째로 2단계 인증 후 앱 비밀번호를 발급받아 진행하는 방법이 있습니다. 저는 보안을 위해 후자의 방법을 택했습니다.
package com.example.test.config;
import org.springframework.beans.factory.annotation.Value;
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 {
@Value("${spring.mail.host}")
public String host;
@Value("${spring.mail.port}")
public int port;
@Value("${spring.mail.username}")
public String sendEmail;
@Value("${spring.mail.password}")
public String sendPassword;
@Value("${spring.mail.properties.mail.smtp.auth}")
public boolean auth;
@Value("${spring.mail.properties.mail.smtp.starttls.enable}")
public boolean starttlsEnable;
@Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost(host);
mailSender.setPort(port);
mailSender.setUsername(sendEmail);
mailSender.setPassword(sendPassword);
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", auth);
props.put("mail.smtp.starttls.enable", starttlsEnable);
props.put("mail.debug", "true");
return mailSender;
}
}
이어서 MailConfig 파일을 만든 후 JavaMailSender에 @Bean을 통해 의존성을 주입해줍니다. 내부에 application.properties에서 설정한 메일 정보를 @Value를 이용하여 가져옵니다.
...
@Autowired
private JavaMailSender emailSender;
...
...
SimpleMailMessage message = new SimpleMailMessage();
message.setTo({메일을 보내려는 이메일 주소});
message.setSubject("테스트 메일");
message.setText("테스트 메일");
emailSender.send(message);
...
이후 SimpleMailMessage 객체를 이용하여 메일의 정보를 추가하여 JavaMailSender를 이용하여 메일을 전송합니다.
테스트를 진행하면 다음과 같이 콘솔에 메일 발송 로그를 확인하실 수 있습니다.
메일 역시 성공적으로 발송되었습니다. 현재는 로컬 환경에서 진행해서 구글 2단계 비밀번호를 Mac 용으로 발급받았는데 EC2 위에서 전송 시 앱 비밀번호를 어떻게 발급받아야 할 지 추후 다시 진행해보고 포스팅하겠습니다. 긴 글 읽어주셔서 감사합니다!
출처
: https://tk-one.github.io/2020/01/03/smtp/
: https://www.baeldung.com/spring-email
: https://born2bedeveloper.tistory.com/14