유저가 메일 발송 요청을 했을 때, 운영자(관리자)에게 상세 구매 및 사용 내역
메일을 요청할 때 운영자에게 자동으로 알림을 보내는 기능을 구현할 것이다.
- 유저가 웹사이트에서 '상세 구매 및 사용 내역' 메일을 요청 (메일 발송 요청 클릭)
- 운영자에게 알림 메일을 보냄
- 알림 메일에는
"홍길동님이 상세 구매 및 사용 내역 메일 발송 요청을 했습니다."
와 같은 메시지 포함
Kotlin: v 1.9.23
SpringBoot: v 3.2.5
implementation("org.springframework.boot:spring-boot-starter-mail")
운영자의 이메일 주소를 환경 변수에 저장
application.yml나 properties에 파일에 아래 코드를 추가:
application.yml
:
spring
mail:
host: smtp.gmail.com
port: 587
username: 실제 Gmail
password: 구글 계정 비밀번호 or 2단계 인증 앱 비밀번호
properties:
mail:
smtp:
auth: true
starttls:
enable: true
notification:
email: 실제 Gmail(운영자(관리자) 메일)
application.properties
:
notification.email=operator@example.com(실제 Gmail)
# 메일 서버 설정
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=your-email@gmail.com(실제 Gmail)
spring.mail.password=your-password(구글 계정 비밀번호 or 2단계 인증 앱 비밀번호)
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
MailSenderConfig가 뭐냐고?
MailSenderConfig는 스프링에서 이메일 발송 설정하는 클래스임
이거 없으면 이메일 못 보내니까 중요함!
JavaMailSender
라는 Bean
을 만들어서 스프링한테 줌MailSenderConfig
:
import문은 버전 마다 달라서 넣지 않음
@Configuration
class MailSenderConfig {
@Value("\${spring.mail.host}")
private lateinit var host: String
@Value("\${spring.mail.port}")
private lateinit var port: String
@Value("\${spring.mail.username}")
private lateinit var username: String
@Value("\${spring.mail.password}")
private lateinit var password: String
@Bean
fun javaMailSender(): JavaMailSender {
val mailSender = JavaMailSenderImpl()
mailSender.host = host
mailSender.port = port.toInt()
mailSender.username = username
mailSender.password = password
val props: Properties = mailSender.javaMailProperties
props["mail.transport.protocol"] = "smtp"
props["mail.smtp.auth"] = "true"
props["mail.smtp.starttls.enable"] = "true"
props["mail.debug"] = "true"
return mailSender
}
}
예시 코드이므로 상황에 맞게 코드 수정이 필요함
@Service
class EmailService(private val emailSender: JavaMailSender) {
@Value("\${operator.email}")
private lateinit var operatorEmail: String
fun sendNotificationEmail(userEmail: String) {
val message = SimpleMailMessage()
message.setFrom("noreply@example.com")
message.setTo(operatorEmail)
message.setSubject("사용자 메일 발송 요청 알림")
message.setText("$userEmail 님이 상세 구매 및 사용 내역 메일 발송 요청을 했습니다.")
emailSender.send(message)
}
}
예시 코드이므로 상황에 맞게 코드 수정이 필요함
@RestController
class UserController(private val emailService: EmailService) {
@PostMapping("send-email")
fun sendEmailRequest(
// 사용자 인증 과정이 필요(ex. SpringSecurity)
): String {
// 사용자 인증 과정이 필요(ex. SpringSecurity)
return emailService.sendNotificationEmail(request.email)
}
}
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN ... XOAUTH2
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN failed
10:26:23.0208 [ERROR] [com...common.exception.GlobalExceptionHandler] Authentication failed
org.springframework.mail.MailAuthenticationException: Authentication failed
Google 계정 로그인할 때 사용하는 비밀번호를 입력하고 메일 발송 요청을 하게 되면 아래와 같은 이슈가 발생함
인증에 실패했다는 메시지로 해석됨
해결 방법에는 2단계 인증을 설정하고 앱 비밀번호를 만들어 구글 계정 비밀번호 대신 앱 비밀번호를 입력하는 방법이 있음
앱 비밀번호를 등록하려면 2단계 인증이 필요함
구글 계정 관리
보안 > 2단계 인증 설정
2단계 인증 설정 후 앱 비밀번호 생성
application.yml
이나 properties
의 password
에 복사 붙여넣기비밀번호나 민감한 정보는 코드에 직접 쓰지 말고 환경 변수로 빼는 게 더 안전함
이메일 보내기 설정 완료!