spring boot

[spring boot] 이메일 본인 인증 만들기

blackzapato 2020. 4. 28. 16:13
반응형

쇼핑몰 토이 프로젝트를 만들면서 회원가입시 이메일 본인 인증이 필요했다.

email로 아이디를 만들고 아이디 중복 확인 후

유저가 작성한 이메일로 인증 코드를 보내고

메일로 보낸 코드와 유저가 메일을 받고 작성한 코드가 일치되면 계속해서

회원가입을 작성하게하는 방식으로 만들어봤다. 

 

1. mail.properties 작성

2. EmailConfig 작성

3. EmailServiceImpl 작성

4. controller작성

5. 작동 확인

 

mail.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 구글 아이디 계정 id,password
AdminMail.id = 구글 아이디
AdminMail.password = 구글 비밀번호

properties는 이클립스에서 ctrl + n 후 untitled text file로 내용 작성 후에 본인 프로젝트내의 resources 안에 넣는다.

 

 

EmailConfig.java

import java.util.Properties;

import org.springframework.beans.factory.annotation.Qualifier;
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;
import org.springframework.stereotype.Component;

@Configuration
@PropertySource("classpath:mail.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 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", startlls_required);
		    pt.put("mail.smtp.socketFactory.fallback",fallback);
		    pt.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
			return pt;
		}
	    

}

 

저는 인증키를 만든후에 static으로 값을 넣어 사용하지만 실제로는 DB에 컬럼하나를 만들어 저장 후

비교 하시는걸 추천합니다.

 

EmailServiceImpl.java

import java.util.Random;

import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

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 OtherService{
	
	@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("BZshop 인증번호가 도착했습니다.");//제목
	        
	        String msgg="";
	        msgg+= "<div style='margin:100px;'>";
	       	msgg+= "<h1> 안녕하세요  BZshop입니다!!! </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("properties에 작성한 이메일","BZshop"));//보내는 사람
	        
	        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 void 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();
		        }
		
	}

}

 

여기서 OtherService는 본인이 사용하는 비슷한 목적의 interface에 코드 한 줄만 추가하고 implements하면 된다.

createKey 메소드는 간단하게 개인 프로젝트 용도로 사용할 것이기 때문에(DB에 접근해야 할 수고를 덜기 위해)

static으로 설정해줬지만 인터넷으로 이메일 인증 서비스를 하는 본래의 경우라면 유저 테이블에 컬럼을 하나 더 추가를 하던 새로 테이블을 하나 더 추가를 하던 해서 인증 키값을 따로 관리하는 것이 맞다.

 

인증키 값을 더욱 간단하게 만들고 싶다면 아래 글을 참조하시면 됩니다 :)

2021.07.22 - [spring boot] - [springboot] 문자+숫자, 숫자 6자리 난수 만들기

 

[springboot] 문자+숫자, 숫자 6자리 난수 만들기

회원가입 시 이메일 인증을 사용하면서 6자리를 만들어주는 난수발생기가 필요했다. import java.util.Random; public class HelloWorld{ public static void main(String []args){ StringBuffer key = new String..

badstorage.tistory.com

 

ServiceController.java

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.blackzapato.demo.service.EmailServiceImpl;
import com.blackzapato.demo.service.OtherService;

@Controller
@RequestMapping("/service/*")
public class ServiceController {
	 @Autowired
	 OtherService service;
	 
	 private static final Logger logger = LoggerFactory.getLogger(MemberController.class);
	 
		@PostMapping("/mail")
		@ResponseBody
		public void emailConfirm(String userId)throws Exception{
			logger.info("post emailConfirm");
			System.out.println("전달 받은 이메일 : "+userId);
			service.sendSimpleMessage(userId);	
		}
		@PostMapping("/verifyCode")
		@ResponseBody
		public int verifyCode(String code) {
			logger.info("Post verifyCode");
			
			int result = 0;
			System.out.println("code : "+code);
			System.out.println("code match : "+ EmailServiceImpl.ePw.equals(code));
			if(EmailServiceImpl.ePw.equals(code)) {
				result =1;
			}
			
			return result;
		}
}

 

적용 후

중복 확인 후 인증 버튼 생성
인증 버튼 클릭후 이메일 발송 
이메일 내용
인증코드 작성
본인 인증 성공 후 

 

 

 

위와 같이 적용 후 추가로 적용할 수 있는 코드

 

 

2020/09/22 - [javascript] - [javascript] 이메일 인증번호 타이머(유효시간 연장기능)

 

[javascript] 이메일 인증번호 타이머(유효시간 연장기능)

이메일을 보냄과 동시에 타이머를 작동시켜 일정 시간이 지나면 인증번호를 입력하지 못하도록 막는 기능을 구현중에 유효시간 연장이라는 기능도 같이 만들어야 했다. 어영부영 만들어 놓고 �

badstorage.tistory.com

 

반응형