[Kotlin] Spring Boot로 메일(Gmail) 발송하기

·2024년 9월 9일
0

Kotlin

목록 보기
1/1
post-thumbnail

유저가 메일 발송 요청을 했을 때, 운영자(관리자)에게 상세 구매 및 사용 내역 메일을 요청할 때 운영자에게 자동으로 알림을 보내는 기능을 구현할 것이다.

기능 개요:

  1. 유저가 웹사이트에서 '상세 구매 및 사용 내역' 메일을 요청 (메일 발송 요청 클릭)
  2. 운영자에게 알림 메일을 보냄
  3. 알림 메일에는 "홍길동님이 상세 구매 및 사용 내역 메일 발송 요청을 했습니다." 와 같은 메시지 포함

개발 환경

Kotlin: v 1.9.23
SpringBoot: v 3.2.5

Gradle 의존성 추가 (build.gradle)

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가 뭐냐고?

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
    }
}

EmailService

예시 코드이므로 상황에 맞게 코드 수정이 필요함

@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)
    }
}

EmailController

예시 코드이므로 상황에 맞게 코드 수정이 필요함

@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단계 인증을 설정하고 앱 비밀번호를 만들어 구글 계정 비밀번호 대신 앱 비밀번호를 입력하는 방법이 있음

Google 계정 설정, Gmail 설정

앱 비밀번호를 등록하려면 2단계 인증이 필요함

  1. 구글 계정 관리

  2. 보안 > 2단계 인증 설정

  3. 2단계 인증 설정 후 앱 비밀번호 생성

  • 앱 비밀번호를 검색한 후 앱 비밀번호 생성, 앱 비밀번호 키 저장
  • application.yml 이나 propertiespassword에 복사 붙여넣기





비밀번호나 민감한 정보는 코드에 직접 쓰지 말고 환경 변수로 빼는 게 더 안전함
이메일 보내기 설정 완료!

profile
돈많은 백수가 꿈인 개발자 혹은 엔지니어

0개의 댓글