[Spring] 이메일 인증
2023. 8. 26. 11:01ㆍWeb/Spring
[Spring] 이메일 인증 - Spring Boot Starter Mail 사용
개인 학습용 프로젝트에 이메일 인증을 적용하면서 진행했던 과정을 정리하려고 한다.
사용한 API는 Spting Boot Starter Mail을 사용하였다.
Spting Boot Starter Mail
- Spring Boot에서 제공하는 라이브러리 중 하나
- 이메일을 보내기 위한 라이브러리
- JavaMailSender 인터페이스를 구현하여 이메일을 보내는 용도로 사용 가능
- Spring Boot에서는 JavaMailSender를 자동으로 구성하기에 별도의 설정 없이 사용가능
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail/3.1.3
- build.gradle에 해당 코드 추가
implementation 'org.springframework.boot:spring-boot-starter-mail:3.1.2'
메일 및 환경설정
코드를 작성하기 전 사용하고자 하는 메일 계정에서 POP3/SMTP 설정을 해야 한다.
- POP3 / SMTP 설명
- POP3와 SMTP는 이메일 클라이언트에서 이메일을 보내고 받기 위해 필요한 설정
- POP3
- 이메일을 수신하는 데 사용하는 프로토콜
- 단방향 전자 메일 동기화만 지원
- 사용자는 서버에서 클라이언트로 전자 메일을 다운로드하는 것만 허용
- SMTP
- 이메일 발송을 위해 사용되는 프로토콜
- 네이버
- 메일 - 환경설정 - POP3/SMTP 설정
설정이 끝나면 사용할 정보를 application.properties 혹은 application.yml 파일에 넣어준다. 만약 해당 정보를 암호화를 하지 않고 사용한다면. gitignore를 해야 한다.
java-mail:
hostname: ENC(EPeQgROSy1+/Ev6pMXGeYea5cwMwRQlX)
identifier: ENC(Hfd5ajAKGVf9PldJtig0JQ==)
password: ENC(dJIuacH5gbfOZHlDDHJkVfZMHaRdXLIa)
port: ENC(T4AuzQ7+K9X0O3rHuBQieA==)
required: ENC(+DYTR8SjtLbdeacbFPUBjA==)
이번 프로젝트에서는 yml을 사용하였기에 yml에 다음과 같이 입력하였다.
yml 내부의 ENC()로 적혀있는 부분은 현재 변환이 된 부분이다.
[Etc] application.yml 변경 및 Jasypt (tistory.com)
Config 및 코드
- Config 코드
@Configuration
public class EmailConfig {
@Value("${java-mail.hostname}")
private String hostname;
@Value("${java-mail.identifier}")
private String identifier;
@Value("${java-mail.password}")
private String password;
@Value("${java-mail.port}")
private String port;
@Value("${java-mail.required}")
private String required;
@Bean
public JavaMailSender javaMailSender() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost(hostname);
javaMailSender.setUsername(identifier);
javaMailSender.setPassword(password);
javaMailSender.setPort(Integer.valueOf(port));
javaMailSender.setJavaMailProperties(getMailProperties());
return javaMailSender;
}
private Properties getMailProperties() {
Properties properties = new Properties();
properties.setProperty("mail.smtp.ssl.trust", hostname);
properties.setProperty("mail.transport.protocol", "smtp");
properties.setProperty("mail.smtp.auth", required);
properties.setProperty("mail.smtp.starttls.enable", required);
properties.setProperty("mail.debug", required);
properties.setProperty("mail.smtp.ssl.enable", required);
return properties;
}
}
- Controller
@RequiredArgsConstructor
@RestController
@RequestMapping(VERIFIED_API_URI)
public class EmailController {
private final EmailVerifiedService emailVerifiedService;
@PostMapping("/email")
public String checkEmailVerified(@RequestParam("email") String email)
throws MessagingException, UnsupportedEncodingException {
String emailResponse = emailVerifiedService.sendSimpleMessage(email);
return emailResponse;
}
}
- Service
@Service
@RequiredArgsConstructor
@Slf4j
public class EmailVerifiedServiceImpl implements EmailVerifiedService{
private final JavaMailSender javaMailSender;
private String ePw;
@Override
public MimeMessage createMessage(String to)
throws MessagingException, UnsupportedEncodingException {
MimeMessage message = javaMailSender.createMimeMessage();
message.addRecipients(RecipientType.TO, to);
message.setSubject("SkillBack 이메일 인증");
ePw = createKey();
String msg = "";
msg += "<div style='margin:100px;>";
msg += "<h1> 안녕하세요. skillBack 입니다 </h1>";
msg += "<br>";
msg += "<p>아래 코드를 창으로 돌아가서 입력하시면 됩니다<p>";
msg += "<br>";
msg += "<div align='center' style='border:1px solid black; font-family:verdana';>";
msg += "<h3 style='color:black;'>인증 코드입니다.</h3>";
msg += "<div style='font-size:130%'>";
msg += "CODE : <strong>";
msg += ePw + "</strong><div><br/> "; // 메일에 인증번호 넣기
msg += "</div>";
message.setText(msg, "utf-8", "html");
message.setFrom(new InternetAddress("gn1007@naver.com", "skill_Admin"));
return message;
}
private String createKey() {
StringBuffer stringBuffer = new StringBuffer();
Random random = new Random();
for (int i = 0; i < 8; i++) {
int i1 = random.nextInt(3);
switch (i1) {
case 0:
stringBuffer.append((char) ((int) (random.nextInt(26)) + 97));
break;
case 1 :
stringBuffer.append((char) ((int) (random.nextInt(26)) + 65));
break;
case 2:
stringBuffer.append((random.nextInt(10)));
break;
}
}
return stringBuffer.toString();
}
@Override
public String sendSimpleMessage(String to)
throws MessagingException, UnsupportedEncodingException {
MimeMessage message = createMessage(to);
try {
javaMailSender.send(message);
} catch (MailException e) {
e.printStackTrace();
throw new IllegalArgumentException("이메일 발송 실패");
}
return ePw;
}
}
Test - PostMan
진행하는 프로젝트에서는 이메일 인증의 입력값을 프런트로 전달 후 클라이언트가 입력한 값이 동일한지 프론트 단에서 체크를 할 예정이다. 그렇기에 해당 기능이 잘 작동하는지 postman으로만 테스트를 간단히 진행하였다.
'Web > Spring' 카테고리의 다른 글
[Spring] HTTPS 적용하기 (0) | 2024.02.17 |
---|---|
[Spring] 휴대폰 인증 - 네이버 sens 사용 (0) | 2023.08.26 |
[Error] java.lang.ClassNotFoundException: org.apache.hc.client5.http.classic.HttpClient (0) | 2023.08.17 |
[Etc] application.yml 변경 및 Jasypt (0) | 2023.08.09 |
[Test Code] @WithMockUser / @WithUserDetails / @WithSecurityContext (0) | 2023.01.27 |