Spring

[SpringBoot] 구글 SMTP 통해 메일 보내기

꾸준함. 2022. 4. 10. 00:05

개요

회원 가입 이후 이메일 인증을 한 사용자에게만 서비스 접근을 할 수 있도록 구현하고 싶어 찾아본 결과 구글에서 제공하는 SMTP 서비스를 통해 비교적 쉽게 구현할 수 있었습니다.

단, 구글 SMTP 서비스는 한 이메일 당 하루 100건씩 제한을 걸기 때문에 로컬에서 여러 번 테스트하고 싶을 때는 실제 메일을 보내지 않고 콘솔에 메일 내용을 로그로 작성하는 것을 추천드립니다.

이번 게시글에서는 구글 SMTP 설정과 메일 보내는 방법 그리고 콘솔에 메일 내용을 로그로 작성하는 방법을 간단히 공유해보겠습니다.

 

1. 구글 계정 앱 비밀번호 설정 및 application.properties 설정

구글 SMTP를 사용하기 위해서는 구글 계정 내 앱 비밀번호를 설정해야 합니다.

https://support.google.com/mail/answer/185833

 

앱 비밀번호로 로그인 - Gmail 고객센터

도움이 되었나요? 어떻게 하면 개선할 수 있을까요? 예아니요

support.google.com

 

요약을 하자면 아래와 같습니다.

  • Google 계정 관리 > 보안 > Google에 로그인 > 2단계 인증 설정
  • Google 계정 관리 > 보안 > Google에 로그인 > 앱 비밀번호 설정
    • 앱 선택 > 기타 > SMTP로 설정 후 생성
    • 생성한 비밀번호를 복사

 

위 과정을 모두 거친 뒤에는 아래와 같이 SpringBoot 내 application.properties 혹은 application.yml을 설정해주시면 됩니다.

 

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=[본인 이메일]
spring.mail.password=[복사한 비밀번호]
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.starttls.enable=true

 

2. MailService 구현

application.properties를 설정했다면 이제 실제 메일을 보내는 서비스를 구현하면 됩니다.

MailService는 아래와 같이 구현하면 됩니다.

 

 

  • org.springframework.mail.javamail의 JavaMailSender를 Autowired 받고 해당 객체를 통해 MimeMessage를 전송
  • 메일에 텍스트와 함께 이미지를 같이 보내기 위해서는 MimeMessageHelper 생성자의 두 번째 인자로 true 설정
  • html 템플릿을 통해 메시지를 보낼 거면 setText() 메서드의 두 번째 인자로 true 설정, 그냥 String으로 보낼거면 false 설정

 

2.1 html 템플릿 예시

타임리프를 pom.xml 혹은 gradle에 추가할 경우 TemplateEngine 객체를 Autowired 받을 수 있습니다.

TemplateEngine을 통해 Context를 설정하고 html 템플릿과 연동하면 html 템플릿을 메일 메시지로 보낼 수 있습니다.

 

html

 

 

예시 Service


 

2.2 메일 전송 악용할 경우

앞서 개요에도 언급했다시피 구글 SMTP는 한 계정당 하루 100건으로 메일 전송을 제한합니다.

또한, sendgridmailgun과 같이 제한이 없는 서비스를 사용하더라도 사용자가 메일을 짧은 시간 내 여러 번 보낼 수 있게 되면 트래픽 과부하가 발생해 서비스에 지장을 줄 수가 있습니다.

따라서, 이를 방지하기 위해 동일한 메일에 대해서는 해당 계정으로 최근 x분 혹은 x시간 내 보낸 적이 없어야 재전송할 수 있도록 설정을 해주는 것이 안전합니다.

이를 위해서는 아래와 같이 Account 객체 내 토큰 필드와 함께 토큰 필드 생성 시간 필드를 만들고 이메일 전송 가능 여부를 판별해주는 boolean 메서드를 구현하면 됩니다.

 

* 토큰 필드는 인증 메일 확인용으로 생성된 것인데 이 부분은 생략하도록 하겠습니다.

* 핵심 포인트는 생성 시간 필드를 현재 시간과 비교하여 이메일 전송 가능 여부를 확인하는 것입니다.

 

Account.java


 

예시 Controller + Service


 

3. local 테스트용으로 이메일 내용을 로그만 찍는 방법

앞서 설명한 방법은 SMTP를 통해 실제 메일을 보내는 방법이고 지금부터 작성할 내용은 JavaMailSender를 통해 메일 내용을 로그로 찍는 방법입니다.

구조는 똑같다고 보면 되고 유일하게 다른 점은 MimeMessage가 아닌 SimpleMailMessage 객체를 사용한다는 것입니다.

 

ConsoleMailSender.java


 

ExampleService.java


 

참고

인프런 강의 - 스프링과 JPA 기반 웹 애플리케이션 개발 (백기선 강사님)

 

반응형