커스텀 도메인으로 이메일을 받고 보내는 시스템을 구축하는 방법에 대해 알아보겠습니다. 이 글에서는 Cloudflare Email Routing을 사용하여 커스텀 도메인의 이메일을 Gmail로 포워딩하고, Gmail과 Spring Boot를 설정하여 커스텀 도메인 이메일 주소로 이메일을 발송하는 방법을 단계별로 설명합니다.
목차
- 요구사항
- Cloudflare Email Routing 설정
- Gmail에서 커스텀 도메인 설정
- Spring Boot 이메일 발송 구현
- 문제 해결
- 결론
요구사항
이 시스템의 주요 요구사항은 다음과 같습니다
- 커스텀 도메인 이메일 주소(contact@yourdomain.com)로 보내진 이메일이 Gmail 계정으로 전달되어야 함
- Spring Boot 애플리케이션에서 보내는 이메일의 발신자 주소가 커스텀 도메인 이메일 주소로 표시되어야 함
- Gmail에서 수동으로 이메일을 보낼 때도 커스텀 도메인 이메일 주소가 발신자로 표시되어야 함
Cloudflare Email Routing 설정
전제 조건
- Cloudflare에 도메인이 등록되어 있어야 함
- 도메인의 네임서버가 Cloudflare로 설정되어 있어야 함
설정 단계
- Cloudflare 대시보드에 로그인하고 해당 도메인을 선택합니다.
- 좌측 메뉴에서 "Email" 탭을 클릭한 다음 "Email Routing"을 선택합니다.
- "Get Started" 버튼을 클릭하여 Email Routing을 활성화합니다.
이메일 라우팅 규칙 설정
특정 이메일 주소에 대한 포워딩 규칙을 생성합니다
- "Create Route" 버튼을 클릭합니다.
- "Custom Address" 옵션을 선택하고 원하는 이메일 주소(예: contact@yourdomain.com)를 입력합니다.
- "Action"에서 "Send to"를 선택하고 이메일을 받을 Gmail 주소를 입력합니다.
- "Save" 버튼을 클릭하여 규칙을 저장합니다.
이 설정을 완료하면 contact@yourdomain.com으로 보내진 모든 이메일이 지정한 Gmail 계정으로 자동 전달됩니다.
Gmail에서 커스텀 도메인 설정
Gmail에서 커스텀 도메인 이메일을 사용하기 위한 설정을 진행합니다.
Gmail에서 커스텀 도메인 발신자 설정
Gmail에서 커스텀 도메인 이메일 주소로 발신하려면 "다른 이메일 주소로 메일 보내기" 기능을 설정해야 합니다
- Gmail 설정으로 이동합니다
- Gmail 오른쪽 상단의 설정 아이콘(⚙️) 클릭
- "모든 설정 보기" 클릭
- "계정 및 가져오기" 탭으로 이동합니다.
- "다른 주소에서 메일 보내기" 섹션에서 "다른 이메일 주소 추가" 링크를 클릭합니다.
- 팝업 창에서 다음 정보를 입력합니다
- 이름: 수신자에게 표시될 이름 (예: "회사명" 또는 "서비스명")
- 이메일 주소: 커스텀 도메인 이메일 주소 (예: contact@yourdomain.com)
- "다음 단계" 버튼 클릭
- SMTP 서버 설정을 입력합니다
- SMTP 서버: smtp.gmail.com
- 포트: 587
- 사용자 이름: 본인의 Gmail 주소 (예: your-gmail@gmail.com)
- 비밀번호: Gmail 계정 비밀번호 또는 앱 비밀번호
- "TLS 사용" 선택 (일반적으로 기본 선택됨)
- "계정 추가" 버튼 클릭
- Google에서 발송한 확인 코드가 포함된 이메일을 확인합니다
- 등록한 이메일 주소로 확인 이메일이 전송됩니다
- Cloudflare Email Routing을 통해 이 이메일이 Gmail로 포워딩되어야 합니다
- 이메일에 포함된 확인 코드를 입력하거나 이메일 내 확인 링크를 클릭합니다
- 설정 완료 후 이메일 작성 시 "보낸 사람" 필드에서 커스텀 도메인 이메일을 선택할 수 있습니다.
이 설정은 Gmail 웹 인터페이스에서 수동으로 이메일을 보낼 때 유용하지만, Spring Boot 애플리케이션에서 프로그래매틱하게 이메일을 보낼 때는 추가 설정이 필요합니다.
앱 비밀번호 생성
Spring Boot 애플리케이션에서 Gmail SMTP 서버를 사용하여 이메일을 발송하기 위해 앱 비밀번호를 생성합니다
- Gmail 계정에 2단계 인증을 활성화합니다
- Google 계정 > 보안 > 2단계 인증
- 앱 비밀번호를 생성합니다
- Google 계정 > 보안 > 앱 비밀번호
- "앱 선택"에서 "기타"를 선택하고 이름을 입력(예: "Spring Boot App")
- "생성" 버튼을 클릭하여 16자리 앱 비밀번호를 받습니다
생성된 앱 비밀번호는 안전한 곳에 보관하고, 이후 Spring Boot 설정에 사용합니다.
Spring Boot 이메일 발송 구현
의존성 추가
Kotlin과 Spring Boot를 사용하는 프로젝트에 다음 의존성을 추가합니다.
Gradle (build.gradle.kts)
dependencies {
implementation("org.springframework.boot:spring-boot-starter-mail")
// 기타 필요한 의존성...
}
Maven (pom.xml)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
SMTP 설정
application.yml 파일에 Gmail SMTP 설정을 추가합니다
spring:
mail:
host: smtp.gmail.com
port: 587
username: ${EMAIL_USERNAME:your-gmail@gmail.com}
password: ${EMAIL_PASSWORD:yourapppassword}
properties:
mail:
smtp:
auth: true
starttls:
enable: true
이메일 서비스 구현
Kotlin으로 이메일 서비스를 구현합니다
package com.yourdomain.service
import org.springframework.mail.SimpleMailMessage
import org.springframework.mail.javamail.JavaMailSender
import org.springframework.stereotype.Service
@Service
class EmailService(
private val emailSender: JavaMailSender
) {
fun sendPasswordResetEmail(email: String, resetLink: String) {
val message = SimpleMailMessage()
message.setFrom("contact@yourdomain.com") // 커스텀 도메인 이메일 사용
message.setTo(email)
message.subject = "[서비스명] 비밀번호 재설정 링크"
message.text = """
안녕하세요, 서비스명입니다.
비밀번호 재설정을 위한 링크를 보내드립니다.
아래 링크를 클릭하여 비밀번호를 재설정해주세요:
$resetLink
이 링크는 1시간 동안만 유효합니다.
요청하지 않으셨다면 이 이메일을 무시해주세요.
""".trimIndent()
emailSender.send(message)
}
}
HTML 형식의 이메일 발송 (선택 사항)
HTML 형식의 이메일을 보내려면 MimeMessageHelper를 사용합니다
package com.yourdomain.service
import org.springframework.mail.javamail.JavaMailSender
import org.springframework.mail.javamail.MimeMessageHelper
import org.springframework.stereotype.Service
import javax.mail.MessagingException
@Service
class EmailService(
private val emailSender: JavaMailSender
) {
fun sendPasswordResetEmail(email: String, resetLink: String) {
val message = emailSender.createMimeMessage()
try {
val helper = MimeMessageHelper(message, true)
helper.setFrom("contact@yourdomain.com") // 커스텀 도메인 이메일 사용
helper.setTo(email)
helper.setSubject("[서비스명] 비밀번호 재설정 링크")
// HTML 형식의 이메일 내용
val htmlContent = """
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<h2 style="color: #5d4037;">서비스명 비밀번호 재설정</h2>
<p>안녕하세요, 서비스명입니다.</p>
<p>비밀번호 재설정을 위한 링크를 보내드립니다.</p>
<p>아래 버튼을 클릭하여 비밀번호를 재설정해주세요:</p>
<p style="text-align: center; margin: 25px 0;">
<a href="$resetLink" style="background-color: #795548; color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px;">비밀번호 재설정</a>
</p>
<p>이 링크는 1시간 동안만 유효합니다.</p>
<p>요청하지 않으셨다면 이 이메일을 무시해주세요.</p>
</div>
""".trimIndent()
helper.setText(htmlContent, true) // true는 HTML 사용 가능하게 함
emailSender.send(message)
} catch (e: MessagingException) {
// 예외 처리
throw RuntimeException("이메일 전송 중 오류가 발생했습니다", e)
}
}
}
문제 해결
이메일이 스팸으로 분류되는 문제
이메일이 수신자의 스팸함으로 분류될 경우
- 도메인 인증 설정
- SPF 레코드 설정
- DKIM 설정
- DMARC 설정
- 이메일 내용 최적화
- 스팸으로 분류될 수 있는 단어 사용 자제
- 적절한 제목 사용
- 과도한 링크 사용 자제
결론
지금까지 Cloudflare Email Routing을 사용하여 커스텀 도메인 이메일을 Gmail로 포워딩하고, Spring Boot 애플리케이션에서 Gmail SMTP를 사용하여 커스텀 도메인 이메일 주소로 이메일을 발송하는 방법에 대해 알아보았습니다.
이 방식을 사용하면 다음과 같은 이점이 있습니다
- 별도의 이메일 서버 구축 없이 커스텀 도메인 이메일 사용 가능
- 익숙한 Gmail 인터페이스를 통해 이메일 관리
- Spring Boot 애플리케이션에서 전문적인 도메인 이메일 주소로 이메일 발송
단, 프로덕션 환경에서 대량의 이메일을 발송해야 한다면 Gmail SMTP보다는 SendGrid, Mailgun, Amazon SES와 같은 전문 이메일 서비스를 사용하는 것이 권장될 것 같습니다!
참고 자료: