이번에는 이메일 인증을 하기 위해 SpringBoot에서 이메일 인증 코드를 보내는 것을 해볼려고 한다.
이메일 인증 구현은 링크 이 사이트를 참고해서 실행했다.
시작하기 전 구글 계정 세팅
나는 내 구글 계정을 사용해서 이메일을 보낼려고 한다.
- 크롬에서 오른쪽 상단에 자신의 프로필 클릭하고 구글 계정 관리를 들어간다.
- 왼쪽에 보안이 있다.
- 보안 중 비밀번호 앱 비밀번호를 선택한다.
- 메일 Windows 컴퓨터를 클릭하고 생성을 누른다.
이렇게 하면 16자리의 Spring boot에서 쓸 비밀번호를 얻게 된다.
Gmail 이메일 발송 한도
https://support.google.com/a/answer/166852?hl=ko
이 부분이 Gmail에서 공식적으로 알려주는 전송 한도이다.
Gmail API를 이용할 경우 1회 전송 한도가 100개 이다.
또 하루 최대 매일 수가 나는 무료 체험 계정이므로 500개가 한계이다. 나중에 실무 프로젝트를 할 때 참고해야 겠다.
SpringBoot 세팅
본격적으로 시작하기전에 추가해야 할 것이 있다.
- build.gradle
implementation 'org.springframework.boot:spring-boot-starter-mail'
- resources에 email.properties를 추가한다.
mail.smtp.auth=true
mail.smtp.starttls.required=true
mail.smtp.starttls.enable=true
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
mail.smtp.socketFactory.fallback=false
mail.smtp.port=465
mail.smtp.socketFactory.port=465
# admin 구글 계정
AdminMail.id = 구글 아이디 입력
AdminMail.password = 발급받은 앱 비밀번호를 입력
EmailConfig
EmailConfig는 @Configuration을 붙여준다. 즉, EmailConfig를 설정 정보로 사용할 것 이라는 뜻이다. 그리고 여기에 @Bean이라는 메서드를 모두 호출해서 반환 된 객체를 스프링 컨테이너에 등록할 것이다.
이렇게 해서 의존관계를 설정한다.
Mail을 보내는데에는 SMTP를 사용한다.
SMTP는 Simple Mail Transfer Protocol의 약자로, 이메일을 전송하는 프로토콜이다.
@Configuration
@PropertySource("classpath:email.properties") //properties에 내용 가져옴
public class EmailConfig {
@Value("${mail.smtp.port}")
private int port;
@Value("${mail.smtp.socketFactory.port}")
private int socketPort;
@Value("${mail.smtp.auth}")
private boolean auth;
@Value("${mail.smtp.starttls.enable}")
private boolean starttls;
@Value("${mail.smtp.starttls.required}")
private boolean startlls_required;
@Value("${mail.smtp.socketFactory.fallback}")
private boolean fallback;
@Value("${AdminMail.id}")
private String id;
@Value("${AdminMail.password}")
private String password;
@Bean //의존 관계 주입
public JavaMailSender javaMailSender() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost("smtp.gmail.com"); // 메인 도메인 서버 주소, smtp 서버 주소
javaMailSender.setUsername(id); // 구글 아이디
javaMailSender.setPassword(password); // 구글 비밀번호
javaMailSender.setPort(port); // 메일 인증서버 포트 (gmail = 465, naver = 587)
javaMailSender.setJavaMailProperties(getMailProperties()); //메일 인증서버 정보 가져오기
javaMailSender.setDefaultEncoding("UTF-8");
return javaMailSender;
}
//smtp 서버 정보 설정
private Properties getMailProperties()
{
Properties pt = new Properties();
pt.put("mail.smtp.socketFactory.port", socketPort); //포트 번호
pt.put("mail.smtp.auth", auth); // smtp 인증
pt.put("mail.smtp.starttls.enable", starttls); // smtp strattles 사용
pt.put("mail.smtp.starttls.required", startlls_required);
pt.put("mail.smtp.socketFactory.fallback",fallback);
pt.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); //구글일 경우 이것을 설정해야 함
return pt;
}
}
- mail.smtp.socketFactory.fallback : SMTP 소켓 펙토리를 사용할 수 없는 경우 기본 소켓을 사용할지 여부를 지정하는데 사용한다.
- mail.smtp.starttls.required : SMTP 세션의 TLS(Transport Layer Security) 사용 여부를 지정하는 프로피터이다.
- mail.smtp.socketFactory.class, javax.net.ssl.SSLSocketFactory : 소켓 팩토리 클래스의 이름을 지정하는 프로퍼티이다. "javax.net.ssl.SSLSocketFactory" 클래스는 SSL (Secure Sockets Layer) 프로토콜을 사용하여 암호화된 SMTP 연결을 생성할 수 있는 팩토리 클래스이다.
STARTTLS는 Simple Mail Transfer Protocol (SMTP)에서 제공하는 프로토콜이다.
STARTTLS는 암호화된 전송 계층 (Transport Layer Security, TLS) 연결을 설정하는 것을 가능하게 하는 확장 기능이다. 이 기능은 보안이 필요한 네트워크에서 암호화된 연결을 강제하는 것을 허용한다.
네이버일 경우 properties 설정이 다르다고 한다. 다음에 해봐야 겠다.
EmailService
public interface EmailService {
String sendSimpleMessage(String to)throws Exception;
}
EmialServiceImpl
@Service
@RequiredArgsConstructor
public class EmailServiceImpl implements EmailService {
private final JavaMailSender emailSender;
public static final String key = createKey();
//이메일을 보내는 메소드이다.
@Override
public String sendSimpleMessage(String to) throws Exception {
MimeMessage message = createMessage(to);
try{
emailSender.send(message);
}catch (MailException es){
es.printStackTrace();
throw new IllegalStateException();
}
return key;
}
//보안코드를 만드는 메소드이다.
public static String createKey() {
StringBuffer key = new StringBuffer();
Random rnd = new Random();
for (int i = 0; i < 8; i++) {
int tmp = rnd.nextInt(3);
switch (tmp) {
case 0:
key.append((char) ((int) (rnd.nextInt(26)) + 97));
break;
case 1:
key.append((char) ((int) (rnd.nextInt(26)) + 65));
// A~Z
break;
case 2:
key.append((rnd.nextInt(10)));
// 0~9
break;
}
}
return key.toString();
}
//이메일을 직접적으로 만드는 곳이다.
private MimeMessage createMessage(String to) throws MessagingException, UnsupportedEncodingException {
MimeMessage message = emailSender.createMimeMessage();
message.addRecipients(Message.RecipientType.TO, to);
message.setSubject("WoongProject 인증코드입니다");
String msgg="";
msgg += "<div style='margin:20px;'>";
msgg+= "<h1> 안녕하세요 박세웅입니다. </h1>";
msgg+= "<br>";
msgg+= "<p>아래 코드를 복사해 입력해주세요<p>";
msgg+= "<br>";
msgg+= "<p>감사합니다.<p>";
msgg+= "<br>";
msgg+= "<div align='center' style='border:1px solid black; font-family:verdana';>";
msgg+= "<h3 style='color:blue;'>회원가입 인증 코드입니다.</h3>";
msgg+= "<div style='font-size:130%'>";
msgg+= "CODE : <strong>";
msgg+= key+"</strong><div><br/> ";
msgg+= "</div>";
message.setText(msgg, "utf-8", "html");//내용
message.setFrom(new InternetAddress("lympsw7@gmial.com","ParkSewoong"));//보내는 사람
return message;
}
}
위의 코드들은 모두 구글링을 통해 얻은 뒤 약간씩 변경한 것이다. 보안 코드를 만드는 부분은 대부분 저렇게 구현을 했다. 지금까지 내가 받았던 보안 코드들도 저렇게 만들어진 것 같다.
EmailController
@RestController
@RequiredArgsConstructor
public class EmailController {
private final EmailService emailService;
@PostMapping("/emailSend")
public String emailSend(@RequestParam String email) throws Exception{
String key = emailService.sendSimpleMessage(email);
return key;
}
}
실행
나의 다른 이메일인 네이버 이메일로 인증 코드를 받아보았다.
인증 코드가 전송된 것을 확인할수 있다!!!!
'토이프로젝트 > 나만의 프로젝트' 카테고리의 다른 글
Docker로 CI/CD 구축하기 (0) | 2023.06.20 |
---|---|
데이터베이스 정규화 하기 (2) | 2023.04.29 |
OAuth2.0 이란? (2) | 2023.02.07 |
Spring Boot와 JWT를 이용한 회원 가입(2) (0) | 2023.02.05 |
Spring Boot와 JWT를 이용한 회원 가입(1) (0) | 2023.02.05 |