| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Strict
- ES5
- 데이터베이스 #try #이중
- 1px border
- jwt
- 타입스크립트
- entity
- 으
- TS
- Websocket
- 0.75px border
- 컴포넌튼
- Props
- 전역변수
- literal
- 문서번호
- 0.5px border
- 서버리스 #
- &연산
- 0.25px border
- github
- 클론코딩
- font-size
- ZOOM
- 10px
- TypeScript
- npm
- 당근마켓
- es6
- angular
Archives
- Today
- Total
복잡한뇌구조마냥
[Spring] SMTP 기반 메일 인증 ( + 비동기 처리 ) 본문
1. SMTP란 무엇인가?
SMTP(Simple Mail Transfer Protocol)는
애플리케이션 → 메일 서버 → 사용자의 메일함
으로 메일을 전달하는 메일 전송 프로토콜이다.
Spring Boot에서는 내부적으로 SMTP 서버(Gmail, Naver, Outlook, 회사 SMTP 등)에 접속해서
로그인 → 메일 전송 → 서버가 사용자에게 전달
이라는 과정을 수행한다.
우리가 할 일은 단순히 SMTP 서버 설정 + JavaMailSender 호출뿐이다.
2. Spring Boot SMTP 설정 (application.yml)
프로젝트에서는 보안상 메일 정보를 환경변수로 분리해두고 아래와 같이 설정했다.
spring:
mail:
host: ${SPRING__MAIL__HOST}
port: ${SPRING__MAIL__PORT}
username: ${SPRING__MAIL__USERNAME}
password: ${SPRING__MAIL__PASSWORD}
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
✔ 주요 설정 요약
| 항목 | 설명 |
| host | SMTP 서버 주소 (smtp.gmail.com, smtp.naver.com 등) |
| port | 587(STARTTLS), 465(SSL) |
| auth: true | SMTP 로그인 필요 설정 |
| starttls.enable: true | TLS 기반 암호화로 안전하게 전송 |
| starttls.required: true | TLS 사용이 필수 |
환경변수로 분리한 이유는 다음 두 가지다:
- 깃허브에 메일 계정 비밀번호 노출 방지
- 로컬/배포 환경마다 다른 계정을 유연하게 사용할 수 있음
의존성 추가
implementation("org.springframework.boot:spring-boot-starter-mail")
3. JavaMailSender로 이메일 발송하기
Spring Boot는 JavaMailSender Bean을 자동으로 생성해주기 때문에 바로 주입해서 사용할 수 있다.
📌 이메일 발송 서비스
@Service
@RequiredArgsConstructor
public class EmailSender {
private final JavaMailSender mailSender;
@Async("emailExecutor")
public void sendMailAsync(String email, String code) {
String subject = "[Chwi-Meet] 이메일 인증코드 안내";
String content = """
안녕하세요.
이메일 인증을 위해 아래 인증코드를 입력해주세요.
인증코드: %s
유효시간: 5분
감사합니다.
""".formatted(code);
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(email);
message.setSubject(subject);
message.setText(content);
mailSender.send(message);
}
}
✔ SimpleMailMessage를 사용하는 이유
- 제목, 본문, 수신자만 필요할 때 사용
- HTML 메일이나 첨부파일이 필요하면 MimeMessageHelper 사용
4. 비동기 처리(@Async) 적용 이유
메일 전송은 외부 SMTP 서버와의 통신이 포함되어 있어서 지연 시간이 발생할 수 있다.
그 지연을 모두 API 응답 시간으로 포함시키면 다음과 같은 문제가 생긴다:
- 회원가입 API 응답이 느려짐
- 인증 요청을 여러 번 호출하면 서버 쓰레드 점유됨
- 사용자가 UI에서 “버튼이 안 눌림” 같은 문제를 경험
그래서 메일 전송은 메인 스레드가 아닌 별도 스레드에서 처리하도록 @Async를 붙였다.
- 동기

- 비동기

📌 비동기 전용 쓰레드풀 설정
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "emailExecutor")
public Executor emailExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(5);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("email-");
executor.initialize();
return executor;
}
}
결과
- API는 즉시 응답하고
- 메일은 백그라운드에서 안전하게 발송됨
- SMTP 서버 지연이 있어도 사용자 경험에 영향 없음
5. 이메일 인증 Flow 정리
정확한 인증 흐름을 기록해두면 다음에 재사용하기 편하다.
- 사용자가 이메일 인증 요청
- 서버에서 인증코드 생성 (ex. 6자리 숫자)
- Redis에 5분 TTL로 저장
- EmailSender.sendMailAsync() 호출
- 사용자에게 메일 도착
- 입력된 인증코드와 Redis 저장값 비교
- 성공 → 인증 완료 처리
구조가 간단해보여도 실제 서비스에서는
보안/속도/안정성을 모두 고려해야 하기 때문에
SMTP 설정 + 비동기 처리는 꼭 필요한 구성이다.
마무리
정리하자면 Spring Boot에서 이메일 인증 기능은 다음 두 가지면 완성된다.
- SMTP 설정 → application.yml
- JavaMailSender로 발송 + @Async 처리
이번 프로젝트에서 메일 인증 속도는
기본 2~3초에서 100ms 이하로 개선되었고,
API 응답 성능에도 영향을 주지 않는 구조로 마무리할 수 있었다.
LIST
'BE > Spring' 카테고리의 다른 글
| [Java] TTL 캐시를 직접 구현하며 이해한 Redis 내부 구조 (0) | 2025.12.26 |
|---|---|
| [Spring] Flyway DB 스키마 관리 (0) | 2025.12.07 |
| [Spring] Spring Batch + Scheduler 정리 (0) | 2025.11.27 |
| [JPA] OSIV ( Open Session In View ) (0) | 2025.11.25 |
| [Spring] JOOQ ( + QueryDSL vs JOOQ ) (0) | 2025.11.21 |