JAVA MailSender를 활용해서 이메일 인증만들기
기본적으로 GMAIL을 사용할 것이다. 이메일인증을 만들었기 때문에 같이 소개하겠다.
SMTP는 Simple Mail Transfer Protocol(간단한 메일 전송 프로토콜)의 약어이다.
이 프로토콜은 전자 메일을 보내는 데 사용되며, 보통 인터넷 상에서 이메일을 전송하는 데 널리 사용된다.
SMTP는 클라이언트-서버 모델을 기반으로 동작한다.
보통 전자 메일 클라이언트(예: 이메일 앱)는 SMTP 클라이언트로 작동하여 이메일을 전송하고 메일 서버는 SMTP 서버로 작동하여 수신자의 메일 서버로 이메일을 전달한다.
SMTP 프로토콜은 기본적으로 TCP/IP 프로토콜 스택 위에서 동작한다.
일반적으로 25번 포트를 사용하여 통신한다.
보안을 위해 SSL(Secure Sockets Layer) 또는 TLS(Transport Layer Security) 암호화를 사용할 수도 있다.
SMTP 프로토콜은 다양한 명령어와 응답 코드를 정의하여 메일 전송과 관련된 동작을 수행한다.
일반적인 SMTP 작업 흐름은 다음과 같다.
1.클라이언트가 SMTP 서버에 연결한다.
2.클라이언트는 송신자의 이메일 주소, 수신자의 이메일 주소, 이메일 제목, 본문 등과 같은 이메일 데이터를 서버로 전송한다.
3.서버는 이메일 데이터를 받고, 이메일을 수신자의 메일 서버로 전달하기 위해 필요한 작업을 수행한다.
4.수신자의 메일 서버가 이메일을 받아들이고, 이메일을 수신자의 이메일 계정으로 배달한다.
5.클라이언트와 서버 간의 연결이 종료된다.
SMTP는 전자 메일의 기본적인 전송을 다루는 프로토콜이며, 전송 중에 메시지를 저장하거나 전송 중 오류를 처리하는 기능은 제공하지 않는다.
이러한 기능은 전자 메일 클라이언트나 메일 서버 소프트웨어에 의해 처리된다.
SMTP는 이메일 시스템의 핵심 구성 요소로 사용되며, 이메일을 전송하는 데 널리 활용된다.
1. GMAIL 설정 - 1
사용하기전 먼저 smtp을 허용해줘야한다.
Gmail - 설정 - 모든설정보기 - 전달 및 POP/IMAP을 들어가준다.
IMAP 액세스 부분에 IMAP사용을 선택해주자.
2. GMAIL 설정 - 2
구글의 지침에 의해서 2단계 인증이 되어 있지 않다면 SMTP기능을 사용할 수 없다. 2단계 인증을 꼭 진행해주자.
본인프로필 - 보안 - 2단계 인증

자바 메일 센더를 사용하기 위해서는 앱 비밀번호라는게 필요하다.
https://support.google.com/accounts/answer/185833?hl=ko
앱 비밀번호는 16자리 비밀번호로, 보안 수준이 낮은 앱 또는 기기가 Google 계정에 액세스할 수 있도록 권한을 부여한다.
앱 비밀번호는 2단계 인증이 사용 설정된 계정에서만 이용할 수 있다.

위 사진의 2단계 인증을 들어간 후 내리면 앱비밀번호가 있다. 들어가서 생성을 해주자.
앱 선택 - 기타 JAVA로 설정하였다.

생성을 하게되면 16자리의 번호를 주게 된다.
이제 자바로 가서 설정을 하면된다.
3. 라이브러리 추가
POM.XML에 라이브러리를 추가해주자.
<!-- https://mvnrepository.com/artifact/jakarta.mail/jakarta.mail-api -->
<dependency>
<groupId>jakarta.mail</groupId>
<artifactId>jakarta.mail-api</artifactId>
</dependency>
스프링부트의 버전에 따라 다를 수 있으니 주의하자.
4. MailConfig
메일을 위한 설정을 해주자.
application.properties에 설정을 해주는 것이 편하다.
spring.mail.host=smtp.gmail.com
spring.mail.port=465
spring.mail.username=이메일
spring.mail.password=앱비밀번호
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
host는 smtp.gmail.com 고정이다. naver나 다른 메일은 다르다. 검색해서 사용하자
port는 이 SMTP의 포트이다. 각 사이트마다 다르다. GMAIL은 465포트를 사용한다.
username에는 사용하는 이메일을 넣어준다.
password에는 원래는 비밀번호인데 구글 보안상 앱비밀번호를 무조건 생성하고 넣어줘야한다.
auth는 권한과 관련한 설정이다. 이메일을 보낼때 smtp서버에 로그인 인증정보를 제공하기 위해서 이름과 비밀번호를 제공한다는 것이다.
starttls.enable은 SMTP 서버와의 통신에 대해 STARTTLS(TLS 보안 계층 시작)를 사용하도록 지정한다. STARTTLS는 암호화된 연결을 설정하기 위해 사용되며, 보안을 강화하여 이메일의 내용을 안전하게 전송한다.
@Configuration
public class MailConfig {
@Value("${spring.mail.port}")
private int port;
@Value("${spring.mail.host}")
private String host;
@Value("${spring.mail.username}")
private String username;
@Value("${spring.mail.password}")
private String password;
@Value("${spring.mail.smtp.auth")
private String auth;
@Value("${spring.mail.smtp.starttls.enable")
private String starttls;
@Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost(host);
javaMailSender.setPort(port);
javaMailSender.setUsername(username);
javaMailSender.setPassword(password);
Properties properties = javaMailSender.getJavaMailProperties();
properties.put("mail.smtp.starttls.enable", true);
properties.put("mail.transport.protocol", "smtp");
properties.put("mail.smtp.auth", auth);
properties.put("mail.debug", "false"); // debug true로하면 설정정보 출력됨
properties.put("mail.smtp.ssl.enable", "true");
return javaMailSender;
}
}
이외에도 추가적인 설정을 해줘야한다.
JavaMailSender 객체를 직접 @Bean을 통해서 등록해주자.
host, port, usernmae, password는 set함수를 통해 직접 설정해준다.
기타 설정들은 Properties객체를 만들어서 map처럼 넣어서 사용해주자.
전에 설정한 설정들은 같은 이름으로 값을 넣어주고
mail.transport.protocol은 smtp로 설정해주고
"mail.smtp.ssl.enable은 true로 설정해주는데 JavaMailSender는 SSL을 사용하여 SMTP 서버와의 통신을 암호화한다.
이는 데이터의 보안을 강화하고 외부로부터의 무단 접근을 방지한다.
SSL은 안전한 통신을 위해 공개 키 암호화를 사용하는 프로토콜로, SMTP 통신이 암호화되어 데이터가 안전하게 전송된다.
꼭 해줘야하는 설정인 것 같다.
5. view
<div class="form-group email-form">
<label for="email">이메일</label>
<div class="input-group mb-3">
<input type="text" class="form-control" name="userEamil1" id="userEmail1" placeholder="이메일">
<select class="form-control me-3" name="userEmail2" id="userEmail2">
<option value="@naver.com">@naver.com</option>
<option value="@daum.net">@daum.net</option>
<option value="@gmail.com">@gmail.com</option>
</select>
<input id="emailInput" name="email" type="hidden" />
<div class="input-group-addon">
<button type="button" class="btn btn-primary" id="mail-Check-Btn">본인인증</button>
</div>
</div>
<div class="d-none form-text text-primary" id="availableEmailMessage">
<i class="fa-solid fa-check"></i>
사용 가능한 이메일입니다.
</div>
<div class="d-none form-text text-danger" id="notAvailableEmailMessage">
<i class="fa-solid fa-triangle-exclamation"></i>
사용 불가능한 이메일입니다.
</div>
<div class="mail-check-box mb-3">
<label>인증번호확인</label>
<input class="form-control mail-check-input" placeholder="인증번호 2자리를 입력해주세요!" maxlength="6" id="mailconfirm">
</div>
<div id="emailconfirmTxt mb-3"></div>
</div>
앞부분은 직접 입력하고 뒷부분은 select박스를 이용해서 작성한다.
이메일 관련해서 이런식으로 작성해도되고 직접 작성하게 해서 메일을 위한 full 이메일을 어떻게든 완성해줘야한다.
본인인증버튼을 누르면 메일이 날라가게 되고 인증번호를 입력하면 프론트에서 비교를해서 인증을 하는 것으로 작성하였다.
중간에 사용가능한 이메일 사용불가능한 이메일은 중복처리와 관련된 내용이다.
5. ajax
메일을 보내기 위해 ajax요청을 할 것이다.
view와 관련한 부분은 알아서 처리를 하시길 바란다.
먼저 첫 컨트롤러로 요청을 보내서 메일을 보내고 중복체크를 하게된다.
이메일을 전달해서 있다면 map에 available을 키로 true값이나 fasle값을 받아오게 했다.
이후 중복이 아니라면 인증 절차를 진행하는 ajax를 다시 보내게 된다.
여기서 오는 응답은 인증코드이다.
chkEmailConfirm에 응답으로온 인증코드와 mailconfirm emailconfirmTxt객체 를 넘겨준다.
const mailconfirm = $("#mailconfirm");
const emailconfirmTxt = $("#emailconfirmTxt");
$('#mail-Check-Btn').click(function() {
const email = $("#userEmail1").val();
const site = $("#userEmail2").val();
const fullEmail = email + site;
$("#emailInput").val(fullEmail);
// 입력한 Email을 ajax 요청 보내서
$.ajax("/member/checkEmail/" + fullEmail, {
success: function(data) {
if (data.available) {
// 사용가능하다는 메세지 출력
$("#availableEmailMessage").removeClass("d-none");
$("#notAvailableEmailMessage").addClass("d-none");
checkEmail = true;
$.ajax("/member/mailCheck", {
type: "POST",
data: {
"email": fullEmail
},
success: function(data) {
alert("해당 이메일로 인증번호 발송이 완료되었습니다. \n 확인부탁드립니다.")
//메일확인하러가기 힘들어서 설정 나중에 삭제필요
console.log(data);
chkEmailConfirm(data, mailconfirm, emailconfirmTxt);
}
});
} else {
// 사용가능하지 않다는 메세지 출력
$("#availableEmailMessage").addClass("d-none");
$("#notAvailableEmailMessage").removeClass("d-none");
checkEmail = false;
}
},
})
});
// 이메일 인증번호 체크 함수
function chkEmailConfirm(data, mailconfirm, emailconfirmTxt) {
mailconfirm.on("keyup", function() {
if (data != mailconfirm.val()) { //
emailConfirmChk = false;
emailconfirmTxt.html(`
<div class="form-text text-danger" id="emconfirmchk">
<i class="fa-solid fa-check"></i>
인증 번호가 틀립니다
</div>`)
} else { // 아니면 중복아님
emailConfirmChk = true;
emailconfirmTxt.html(`
<div class="form-text text-primary" id="emconfirmchk">
<i class="fa-solid fa-check"></i>
인증 완료 되었습니다
</div>`)
enableSubmit();
}
})
}
키업 이벤트를 통해서 확인 박스의 값이 들어올때마다 컨트롤러에서 반환받은 인증번호와 비교하게 했다.
만약 같은 값이면 인증이 완료되었음을 알리고 submit버튼이 활성화 되도록 했다.
위에는 없지만 signupSubmit을 처음에는 disabled해놓고 각 체크 과정속에서 true로 만들어서 다 true가 되면 활성화하는 코드를 추가했다.
let checkEmail = false;
let emailConfirmChk = false;
function enableSubmit() {
if (checkEmail & emailConfirmChk) {
$("#signupSubmit").removeAttr("disabled");
} else {
$("#signupSubmit").attr("disabled", "");
}
}
컨트롤러부터는 다음 글에서 작성하겠다.
'개념정리' 카테고리의 다른 글
| 2023.06.28 105일차 인텔리제이 배우기 (0) | 2023.07.15 |
|---|---|
| JAVA MailSender (SMTP)활용해서 GMAIL보내기, 이메일인증 -2 (0) | 2023.06.23 |
| OGNL이란 (0) | 2023.05.01 |
| MYSQL workbench readonly상태 해제 (0) | 2023.04.19 |
| Path (0) | 2023.04.04 |