회원가입 메일인증

이은지·2025년 1월 19일
0

공부한거

목록 보기
1/1

요구사항

개발환경

Java 1.8
Spring 4.2.4
Maven
MySQL,MariaDB
eclipse

메일인증 로직

  1. 이메일 설정 추가
    테스트를 위해 개인계정으로 설정
[pom.xml]
<dependency>
  <groupId>javax.mail</groupId>
  <artifactId>mail</artifactId>
  <version>1.4.7</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>${spring.maven.artifact.version}</version>
</dependency>
[config.properties]
# 이메일 설정 추가
spring.mail.host=smtp.gmail.com
spring.mail.port=465
spring.mail.username=사용할 이메일 작성
spring.mail.password=2차인증

spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.socketFactory.port=465
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.fallback=false
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
  1. Util함수 생성
  • [MailUtils.java]
public class MailUtils {
    
    private static String user_email;
    private static String user_pw;
    private static String smtp_host;
    private static int smtp_port;

    static {
        try (InputStream input = MailUtils.class.getClassLoader().getResourceAsStream("config.properties")) {
            Properties prop = new Properties();
            if (input == null) {
                System.out.println("Sorry, unable to find config.properties");
            }

            prop.load(input);
            
            user_email = prop.getProperty("spring.mail.username");
            user_pw = prop.getProperty("spring.mail.password");
            smtp_host = prop.getProperty("spring.mail.host");
            smtp_port = Integer.parseInt(prop.getProperty("spring.mail.port"));

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
	
    /* 메일 전송 */
    public static void Send(String email, String userName, String userId) throws Exception {
            
            Properties props = System.getProperties();
            props.put("mail.smtp.host", smtp_host); 
            props.put("mail.smtp.port", smtp_port); 
            props.put("mail.smtp.auth", "true"); 
            props.put("mail.smtp.ssl.enable", "true"); 
            props.put("mail.smtp.ssl.trust", smtp_host);
            props.put("mail.smtp.ssl.protocols", "TLSv1.2");
            
            Session session = Session.getInstance(props, new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(user_email, user_pw);
                }
            });

            try {
                
                Message message = new MimeMessage(session);
                message.setFrom(new InternetAddress(user_email));

                // 받는 이메일
                message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email));
        
                // 제목
                message.setSubject("회원가입 인증 메일입니다."); 
        
                // HTML 내용
                String htmlContent = "<!doctype html>\n"
                    + "<html>\n"
                    + "<head>\n"
                    + "<meta charset=\"utf-8\">\n"
                    + "<title>회원가입 인증</title>\n"
                    + "</head>\n"
                    + "<body>\n"
                    + "</body>\n"
                    + "</html>";
                
                // HTML 내용을 설정합니다.
                message.setContent(htmlContent, "text/html; charset=utf-8");
                
                // 발송
                Transport.send(message);
                
            } catch (MessagingException e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
            }
        }
        
	/* 비밀번호 리셋 */
    public static void ResetPw(String email, String userName, String userId) throws Exception {
        
            Properties props = System.getProperties();
            props.put("mail.smtp.host", smtp_host); 
            props.put("mail.smtp.port", smtp_port); 
            props.put("mail.smtp.auth", "true"); 
            props.put("mail.smtp.ssl.enable", "true"); 
            props.put("mail.smtp.ssl.trust", smtp_host);
            props.put("mail.smtp.ssl.protocols", "TLSv1.2");
            
            Session session = Session.getInstance(props, new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(user_email, user_pw);
                }
            });
        
            try {
                Message message = new MimeMessage(session);
                message.setFrom(new InternetAddress(user_email));
        
                // 받는 이메일
                message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email));
        
                // 제목
                message.setSubject("비밀번호 초기화 메일입니다."); 
        
                // HTML 내용
                String htmlContent = "<!doctype html>\n"
                    + "<html>\n"
                    + "<head>\n"
                    + "<meta charset=\"utf-8\">\n"
                    + "<title>새 비밀번호 설정</title>\n"
                    + "</head>\n"
                    + "<body>\n"
                    + "</body>\n"
                    + "</html>";
                
                // HTML 내용을 설정합니다.
                message.setContent(htmlContent, "text/html; charset=utf-8");
                
                // 발송
                Transport.send(message);
                
            } catch (MessagingException e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
            }
        }
        
	/* 메일 재전송 */
    public static void ReSend(String email, int authNumber) throws Exception {
        
        Properties props = System.getProperties();
        props.put("mail.smtp.host", smtp_host); 
        props.put("mail.smtp.port", smtp_port); 
        props.put("mail.smtp.auth", "true"); 
        props.put("mail.smtp.ssl.enable", "true"); 
        props.put("mail.smtp.ssl.trust", smtp_host);
        props.put("mail.smtp.ssl.protocols", "TLSv1.2");
        
        Session session = Session.getInstance(props, new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(user_email, user_pw);
            }
        });

        try {
            
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(user_email));

            // 받는 이메일
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email));

            // 제목
            message.setSubject("회원가입 재인증 메일입니다."); 
    
            // HTML 내용
            String htmlContent = "<!doctype html>\n"
                + "<html>\n"
                + "<head>\n"
                + "<meta charset=\"utf-8\">\n"
                + "<title>회원가입 재인증</title>\n"
                + "</head>\n"
                + "<body>\n"
                + "인증 번호는" + authNumber + "입니다.\n"
                + "</body>\n"
                + "</html>";
            
            // HTML 내용을 설정합니다.
            message.setContent(htmlContent, "text/html; charset=utf-8");
            
            // 발송
            Transport.send(message);
            
        } catch (MessagingException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
    }

}
  1. 메일 인증 로직구현
    3-1. ajax로 post요청

    • [join.jsp]
    $.ajax({
        url: '/registJoinConfirm.ez',
        type: "post",
        data: { 
        	schoolTypeName: $('#schoolTypeList').val(),
            sidoName: $('#sidoList').val(),
        	schoolSeq: $("#schoolList").val(),
        	schoolName: schoolName,
        	userName,
            userId: $("#userId").val(),
            userPw,
            userBirth: fullDate,
            userPhone,
            userEmail,
            groupSeq: $("#groupSeq").val(),
            userAuth: $("#userAuth").val(),
            userType: $("#userType").val(),
            teacherYn: $("#teacherYn").val(),
            agreeRequired: $("input[name='agreeRequired']").val(),
            agreeOptional: $("input[name='agreeOptional']").val()
        },
        dataType: "json",
        success: function(data) {
        	
            if(data.result == "success") {
            	//성공했을때의 로직		
            } else {
                alert("회원가입중 오류가 발생했습니다.");
                return;
            }
        },
        error: function(error) {
            console.log("CreateCutomer Error::", error);
        }
    });

    3-2. controller 연결

    • [joinCustomer.java]
    @RequestMapping(value = "/registJoinConfirm")
    @ResponseBody
    public String customerCreate(@ModelAttribute("userVO") UserVO userVO, HttpServletRequest request, ModelMap model) throws Exception {
    	
    	Map<String, Object> resultMap = new HashMap<>();
    	
         try {
         	 //jsp에서 받은 파라미터 
        	 String schoolTypeName = UDKWebUtil.getParameterValue(request, "schoolTypeName", "");
        	 
             
             if ("on".equals(agreeRequired)) {
        	    agreeRequired = "Y";
             } else {
        	    agreeRequired = "N";
             }
    
             if ("on".equals(agreeOptional)) {
        	    agreeOptional = "Y";
             } else {
        	    agreeOptional = "N";
             }
             String encPw = StringEncrypter.encryptPassword(userPw, userId);
             
             //userVO에 set
             
             joinService.addCustomer(userVO);
             
             //userId encode해서 메일전송
             String encUserId = Base64.getUrlEncoder().encodeToString(userId.getBytes());	         
             
             //2번에서 만든 Util함수 활용
             MailUtils.Send(userEmail, userName, encUserId);
             
             // 회원 삭제 예약
             joinService.scheduleUserDeletion(userId);
                
             resultMap.put("result", "success");
             
         } catch (Exception e) {
        	 logger.error("" + e.getMessage());
        	 resultMap.put("result", "fail");
        	 resultMap.put("error", e.getMessage());
         }
         
         return new Gson().toJson(resultMap);
     }

    3-3. 메일에서 버튼 클릭 시 인증

    • 메일 링크
    <a href=\"http://test.com/mailAuthConfirm.ez?userId="+userId+"\" target=\"_blank\">\n"
    • [joinCustomer.java]
    
    @CrossOrigin
    @RequestMapping(value = "/mailAuthConfirm")
    public String mailAuthConfirm(@RequestParam("userId") String userId, ModelMap model, HttpServletRequest request, HttpServletResponse response) throws Exception {
    	
    	try {
        	//파라미터로 들어온 유저 아이디 복호화
            byte[] decodedBytes = Base64.getUrlDecoder().decode(userId);
            String decUserId = new String(decodedBytes);
        	
        	//DB에서 유저아이디 가져옴
            UserVO getUser = joinService.getUserInfo(decUserId);
            String getUserId = getUser.getUserID();
    
            if (getUserId.equals(decUserId)) {
            	joinService.updateMailAuth(getUserId);
            	model.addAttribute(getUserId);
                return "redirect:/joinCustomer.ez#step4";
            } else {
                return "errorPage";
            }
    
        } catch (Exception e) {
            logger.error("" + e.getMessage());
            return "errorPage";
        }
    }

화면 구성 정리

1) 클라이언트 화면에서 확인버튼 클릭 -> form post 전송

2) 메일전송이 완료된 화면으로 전환, 메일에서 인증하기 버튼 클릭

3) 인증완료 화면 리다이렉트

0개의 댓글