이메일 인증 (spring boot(maven) , jpa)
프로젝트 진행중 이메일 인증을 맡게 되었다.
이메일 보내주는 서비스는 구글 smtp를 이용함.
구현 방식은 db에 저장하지 않고 회원가입 화면에 해당 인증을 진행해야만
회원 가입이 진행되는 과정으로 만들었다.
밑에 참조표시한 블로그를 통해서 대부분 가져다 쓰면서 사용했고
사용하면서 오류가 났었던 부분에 대해서만 언급하고자 한다.
1. 구글 smtp 2단계 인증 후 앱 비밀번호 설정.
구글 아이디랑 비밀번호를 입력했는데 왜 안 계속 오류가 나지 했었는데
구글 아이디와 2단계 인증 후 앱 비밀번호를 입력 해줬어야 했다.
2단계인증을 진행하고 나면
앱 비밀번호를 설정이 가능한데. Google SMTP 를 등록하고 해당 앱 비밀번호를 받아서
email.propertied 에 구글 이메일과 받은 앱 비밀번호를 적으면 된다.
2. Spring boot 와 Maven 버전 일치시키기.
밑에 블로그에는 gradle 버전의 이메일 dependency 밖에 없어서
해당 gradle 검색후 maven 을 찾았을때 가장 그냥 최신의 버전이 가장 좋겠지 하고
3.0 을 사용했었는데 그부분이 생각나서 다시 2.76 에 해당하는 maven 버전을 사용했더니
오류가 수정 되고 잘 진행되었다.
나머진 블로그가 워낙 깔끔하게 설명해줘서 해당 내용을 무리 없이 실행 시킬 수 있었다.
이메일에 도착한 양식이다.
maven dependency 코드 (Spring boot 2.76 버전)
<!-- 이메일 인증 -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.7.6</version>
</dependency>
<!-- 이메일 인증: https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
gradle dependency 코드
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-mail'
}
저는 여기서 maven의 dependency 를 사용했습니다.
Resources/email.properties
해당 부분에 구글 smtp 메일을 보낼 구글 이메일 주소와 2차 인증후 설정가능한 앱 비밀번호를 설정해주면 됩니다.
#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 구글 아이디 계정 id,password
#AdminMail.id = kongdolesmtp@gmail.com
#AdminMail.password = qcuaqktqxamoqidz
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 =kongdolesmtp@gmail.com
AdminMail.password =qcuaqktqxamoqidz
Config/EmailConfig.java
package com.ISOUR.Config;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
@Configuration
@PropertySource("classpath:email.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 starttls_required;
@Value("${mail.smtp.socketFactory.fallback}")
private boolean fallback;
@Value("${AdminMail.id}")
private String id;
@Value("${AdminMail.password}")
private String password;
@Bean
public JavaMailSender javaMailService() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost("smtp.gmail.com");
javaMailSender.setUsername(id);
javaMailSender.setPassword(password);
javaMailSender.setPort(port);
javaMailSender.setJavaMailProperties(getMailProperties());
javaMailSender.setDefaultEncoding("UTF-8");
return javaMailSender;
}
private Properties getMailProperties()
{
Properties pt = new Properties();
pt.put("mail.smtp.socketFactory.port", socketPort);
pt.put("mail.smtp.auth", auth);
pt.put("mail.smtp.starttls.enable", starttls);
pt.put("mail.smtp.starttls.required", starttls_required);
pt.put("mail.smtp.socketFactory.fallback",fallback);
pt.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
return pt;
}
}
Controller/EmailConfirmController
이 부분을 통해서 프론트와 연결하는 곳입니다. 밑에 /isEmailCheck 부분은 이메일 인증과는 무관합니다.
package com.ISOUR.controller;
import com.ISOUR.Service.MemberService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.ISOUR.Service.EmailServiceImpl;
import com.ISOUR.Service.EmailService;
import java.util.Map;
@Slf4j
@CrossOrigin(origins = "http://localhost:3000/")
@RestController
@RequestMapping("/service/*")
public class EmailConfirmController {
@Autowired
EmailService service;
private MemberService memberService;
public EmailConfirmController(MemberService memberService) {
this.memberService = memberService;
}
private static final Logger logger = LoggerFactory.getLogger(MemberController.class);
@PostMapping("/mail")
public void isMemberCheck(@RequestBody Map<String, String> emailData) throws Exception {
String getEmailId = emailData.get("id");
logger.info("post emailConfirm");
System.out.println("전달 받은 이메일 : " + getEmailId);
service.sendSimpleMessage(getEmailId);
}
@PostMapping("/verifyCode")
// @ResponseBody
public Integer verifyCode(@RequestBody Map<String, String> emailCode){
logger.info("Post verifyCode");
Integer result=0;
String getEmailCode = emailCode.get("code");
System.out.println("code : "+getEmailCode);
System.out.println("code match : "+ EmailServiceImpl.ePw.equals(getEmailCode));
if(EmailServiceImpl.ePw.equals(getEmailCode)) {
result =1;
}
return result;
}
@PostMapping("/isEmailCheck")
public ResponseEntity<Boolean> IsEmailCheck(@RequestBody Map<String, String> memberData) {
log.warn("★★★★★★★★★이메일 중복확인 Controller★★★★★★★★★");
String getEmail = memberData.get("email");
log.warn("중복확인할 이메일 주소(email : " + getEmail);
boolean isTrue = memberService.isEmailCheck(getEmail);
if(isTrue) log.warn("중복확인할 이메일(email) boolean 값 : " + isTrue);
if(isTrue) {
log.warn(">>" + isTrue + " : 사용할 수 없는 이메일 입니다. ");
return new ResponseEntity<>(true, HttpStatus.OK);
} else {
log.warn(">>" + isTrue + " : 사용할 수 있는 이메일입니다. ");
return new ResponseEntity<>(false, HttpStatus.OK);
}
}
}
Service/EmailServiceImpl
여기에서 이메일 보냈을때 보여지는 양식과 내용을 설정할 수 있습니다.
package com.ISOUR.Service;
import java.util.Random;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import com.ISOUR.Service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
@Service
public class EmailServiceImpl implements EmailService {
@Autowired
JavaMailSender emailSender;
public static final String ePw = createKey();
private MimeMessage createMessage(String to)throws Exception{
System.out.println("보내는 대상 : "+ to);
System.out.println("인증 번호 : "+ePw);
MimeMessage message = emailSender.createMimeMessage();
message.addRecipients(RecipientType.TO, to);//보내는 대상
message.setSubject("ISOUR 회원가입 이메일 인증");//제목
String msgg="";
msgg+= "<div style='margin:100px;'>";
msgg+= "<h1> 안녕하세요 MBTI Isour 제작자 입니다. </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+= ePw+"</strong><div><br/> ";
msgg+= "</div>";
message.setText(msgg, "utf-8", "html");//내용
message.setFrom(new InternetAddress("kongdolesmtp@gmail.com","MBTIISOUR"));//보내는 사람
return message;
}
public static String createKey() {
StringBuffer key = new StringBuffer();
Random rnd = new Random();
for (int i = 0; i < 8; i++) { // 인증코드 8자리
int index = rnd.nextInt(3); // 0~2 까지 랜덤
switch (index) {
case 0:
key.append((char) ((int) (rnd.nextInt(26)) + 97));
// a~z (ex. 1+97=98 => (char)98 = 'b')
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();
}
@Override
public String sendSimpleMessage(String to)throws Exception {
// TODO Auto-generated method stub
MimeMessage message = createMessage(to);
try{//예외처리
emailSender.send(message);
}catch(MailException es){
es.printStackTrace();
throw new IllegalArgumentException();
}
return ePw;
}
}
Service/EmailService (인터페이스)
이 부분은 바로 위의 EmailService 에 인터페이스 상속을 해주기 위해 만든 페이지에요.
package com.ISOUR.Service;
public interface EmailService {
String sendSimpleMessage(String to)throws Exception;
}
참고한 블로그.
https://badstorage.tistory.com/38
[spring boot] 이메일 본인 인증 만들기
쇼핑몰 토이 프로젝트를 만들면서 회원가입시 이메일 본인 인증이 필요했다. email로 아이디를 만들고 아이디 중복 확인 후 유저가 작성한 이메일로 인증 코드를 보내고 메일로 보낸 코드와 유저
badstorage.tistory.com
https://javaju.tistory.com/100
[Spring Boot] 이메일 인증 회원가입하기 구현
현재 진행하고 있는 프로젝트에서 사용하고 있는 이메일을 이용해 회원가입을 진행할 수 있도록 구현했습니다. 네이버, 구글, 다음 등의 가입되어있는 이메일을 이용하여 해당 이메일로 인증번
javaju.tistory.com