구글 SMTP 서비스 설정
1. 자신의 Gmail로 접속 → 우측 상단 톱니 바퀴 클릭 → 모든 설정 보기 클릭
2. 아래와 같이 IMAP 사용 설정
변경 사항 저장을 눌렀을 때 본인 인증 창이 활성화 되긴 하였음
3. 우측 상단 구글 계정을 클릭 → 구글 계정 관리 클릭
4. 보안 → Google에 로그인하는 방법 → 2단계 인증 설정
설정이 되었다면 넘어가도 됨
5. 상단 검색창에 '앱 비밀번호' 검색하여 앱 이름 입력 후 만들기 → 생성된 비밀번호는 외부에 유출되지 않도록 저장
build.gradle 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-mail'
application.yml 설정 추가
spring:
mail:
host: smtp.gmail.com
port: 587
username: 보낼 이메일(From)
password: 앱비밀번호(16자리)
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
connectiontimeout: 5000
timeout: 5000
writetimeout: 5000
auth-code-expiration-millis: 300000 # 5 * 60 * 1000(밀리초) == 5분
- host
→ Gmail의 SMTP 서버 호스트 - port
→ SMTP 서버의 포트 번호 (Gmail SMTP 서버는 587번 포트) - username
→ 이메일을 보내는 용으로 사용되는 계정의 이메일 주소 입력 - password
→ 위에서 생성했던 앱 비밀번호 입력 - properties
→ 이메일 구성에 대한 추가 속성 - auth
→ SMTP 서버에 인증 필요한 경우 true로 지정
→ Gmail SMTP 서버는 인증을 요구하기 때문에 true 설정 - starttls
→ SMTP 서버가 TLS를 사용하여 안전한 연결을 요구하는 경우 true로 설정
→ TLS는 데이터를 암호화하여 안전한 전송을 보장하는 프로토콜 - connectiontimeout
→ 클라이언트가 SMTP 서버와의 연결을 설정하는 데 대기해야 하는 시간(Millisecond)
→ 연결이 불안정한 경우 대기 시간이 길어질 수 있기 때문에 너무 크게 설정하면 전송 속도가 느려질 수 있음 - timeout
→ 클라이언트가 SMTP 서버로부터 응답을 대기해야 하는 시간(Millisecond)
→ 서버에서 응답이 오지 않는 경우 대기 시간을 제한하기 위해 사용 - writetimeout
→ 클라이언트가 작업을 완료하는데 대기해야 하는 시간(Millisecond)
→ 이메일을 SMTP 서버로 전송하는 데 걸리는 시간을 제한하는데 사용 - auth-code-expiration-millis
→ 이메일 인증 코드의 만료 시간(Millisecond)
MailConfig
- @Value 어노테이션을 이용하여 applicaiton.yml에서 설정한 환경 변수 값들을 가지고 와서 변수에 넣어줌
- JavaMailSenderImpl에 값들을 설정한 뒤 JavaMailSender 인터페이스로 객체 등록
@Configuration
public class MailConfig {
@Value("${spring.mail.host}")
private String host;
@Value("${spring.mail.port}")
private int port;
@Value("${spring.mail.username}")
private String username;
@Value("${spring.mail.password}")
private String password;
@Value("${spring.mail.properties.mail.smtp.auth}")
private boolean auth;
@Value("${spring.mail.properties.mail.smtp.starttls.enable}")
private boolean starttlsEnable;
@Value("${spring.mail.properties.mail.smtp.starttls.required}")
private boolean starttlsRequired;
@Value("${spring.mail.properties.mail.smtp.connectiontimeout}")
private int connectionTimeout;
@Value("${spring.mail.properties.mail.smtp.timeout}")
private int timeout;
@Value("${spring.mail.properties.mail.smtp.writetimeout}")
private int writeTimeout;
@Bean
public JavaMailSender javaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost(host);
mailSender.setPort(port);
mailSender.setUsername(username);
mailSender.setPassword(password);
mailSender.setDefaultEncoding("UTF-8");
mailSender.setJavaMailProperties(getMailProperties());
return mailSender;
}
private Properties getMailProperties() {
Properties properties = new Properties();
properties.put("mail.smtp.auth", auth);
properties.put("mail.smtp.starttls.enable", starttlsEnable);
properties.put("mail.smtp.starttls.required", starttlsRequired);
properties.put("mail.smtp.connectiontimeout", connectionTimeout);
properties.put("mail.smtp.timeout", timeout);
properties.put("mail.smtp.writetimeout", writeTimeout);
return properties;
}
}
MailService
- senderEmail에는 환경 변수로 설정한 보낼 이메일(username)을 저장
→ spring.mail.username에 설정한 email 주소가 보낸 사람(From)이 됨 - createCode() 메서드를 이용하여 인증 코드 6자리 생성
- createMail() 메서드를 이용하여 이메일의 제목, 내용, 보낸사람 등을 설정
@Service
@RequiredArgsConstructor
public class MailService {
private final JavaMailSender javaMailSender;
@Value("{spring.mail.username}")
private static String senderEmail;
public String createCode() {
Random random = new Random();
StringBuilder key = new StringBuilder();
for (int i = 0; i < 6; i++) { // 인증 코드 6자리
int index = random.nextInt(2); // 0~1까지 랜덤, 랜덤값으로 switch문 실행
switch (index) {
case 0 -> key.append((char) (random.nextInt(26) + 65)); // 대문자
case 1 -> key.append(random.nextInt(10)); // 숫자
}
}
return key.toString();
}
public MimeMessage createMail(String mail, String authCode) throws MessagingException {
MimeMessage message = javaMailSender.createMimeMessage();
message.setFrom(senderEmail);
message.setRecipients(MimeMessage.RecipientType.TO, mail);
message.setSubject("이메일 인증");
String body = "";
body += "<h3>요청하신 인증 번호입니다.</h3>";
body += "<h1>" + authCode + "</h1>";
body += "<h3>감사합니다.</h3>";
message.setText(body, "UTF-8", "html");
return message;
}
// 메일 발송
public boolean sendSimpleMessage(String sendEmail) throws MessagingException {
String authCode = createCode(); // 랜덤 인증번호 생성
MimeMessage message = createMail(sendEmail, authCode); // 메일 생성
try {
javaMailSender.send(message); // 메일 발송
return true;
} catch (MailException e) {
return false;
}
}
}
MemberController 코드
@GetMapping("/email/auth/{email}")
public ResponseEntity<String> requestAuthcode(@PathVariable String email) throws MessagingException {
boolean isSend = mailService.sendSimpleMessage(email);
return isSend ? ResponseEntity.status(HttpStatus.BAD_REQUEST).body("인증 코드가 전송되었습니다.") :
ResponseEntity.status(HttpStatus.OK).body("인증 코드 발급에 실패하였습니다.");
}
Postman을 이용하여 인증 코드 발급 확인
'Language > Spring' 카테고리의 다른 글
레디스(Redis) 개념 및 설치 (0) | 2024.08.13 |
---|---|
[Spring Boot] 이메일 인증 코드를 이용한 회원 가입 (0) | 2024.08.13 |
JpaAuditing 사용 방법 및 예제 (0) | 2024.08.12 |
BeanFactory, ApplicationContext (0) | 2024.08.10 |
의존성 주입(DI), 제어의 역전(IoC) (0) | 2024.08.10 |