반응형
Greensky0026
삽질러의 대환장 공사판
Greensky0026
전체 방문자
오늘
어제
  • 분류 전체보기 (241)
    • Language (56)
      • JAVA (13)
      • Swift (38)
      • Kotlin (4)
      • Dart (0)
      • PHP (0)
      • JavaScript (1)
    • IDE & Framework (92)
      • Spring (10)
      • Android (48)
      • iOS (8)
      • NodeJS (1)
      • CodeIgniter (3)
      • Flutter (1)
      • 분류중 (18)
    • Infra (8)
    • Database (12)
    • VCS (4)
    • Debug Log (34)
      • java (7)
      • swift (3)
      • Android (9)
      • Web (7)
      • 삽질기 (7)
    • Others (19)
      • 코딩테스트 풀이 (0)
      • IT 이야기 (18)
    • 쉼터 (2)
    • 개발공부 (14)
      • Network (1)
      • 자료구조와 알고리즘 (2)
      • Code design (8)
      • ETC (1)
      • 아카이브 (1)

블로그 메뉴

    공지사항

    • 프로그래머스 코딩 테스트 관련글 비공개 처리

    인기 글

    태그

    • 프로그래밍
    • map
    • Java
    • ios
    • 구축
    • swift
    • 예제
    • xcode
    • JSP
    • 개발
    • swfit
    • 코딩테스트
    • kotlin
    • Android
    • 공부
    • IT
    • 타입
    • level1
    • reduce
    • 프로그래머스

    최근 댓글

    최근 글

    티스토리

    hELLO · Designed By 정상우.
    Greensky0026

    삽질러의 대환장 공사판

    JSP 회원가입시 이메일 인증 절차 - (4/4) 인증 이메일 전송 및 인증
    IDE & Framework/분류중

    JSP 회원가입시 이메일 인증 절차 - (4/4) 인증 이메일 전송 및 인증

    2021. 5. 30. 01:52
    반응형

     전 포스팅에선 이메일 인증절차까지 완료하였죠? confirmEmail.jsp의 중복확인 결과 분기 부분부터 다시 보겠습니다.

    	<c:set var="emailDupleCheckResult" value="${emailDupleCheckResult }" />
    	<c:choose>
    		<c:when test="${emailDupleCheckResult == 'useable' }">
    			<a>인증메일을 전송중입니다. 팝업창을 허용해주세요.</a>
    			<script type="text/javascript">requestAuthEamil();</script>
    		</c:when>
    		<c:otherwise>
    			<h4> ${email }은 사용 불가능한 email입니다.</h4>
    		</c:otherwise>
    	</c:choose>
    	<br><br>
    	<button type="button" onclick="cancel()" class="btnCancel">확인</button>

    특이사항

    •  JSTL의 choose태그로 이메일 인증결과를 분기
    • 굳이 text를 입력해둔 이유?
      •  요즘은 다 팝업창이 기본설정으로 차단되어 있다보니 사용자 편의를 위해 작성
      •  인증메일을 전송하는 새 창이 크기가 똑같아서 실행되면 어차피 가려서 보이지 않음

    이메일ㅇ ㅣ중복이 아니라면 requestAuthEamil()를 실행

    function requestAuthEamil(){
    	var url = "requestAuthEmail.four?email=" + "<%=email%>";
    	open(url, "authEmailSend",
    		"toolbar=no, location=no,menubar=no,scrollbars=no,resizable=no,width=300,height=200");
    }

    이런 녀석입니다. 받은 email로 또 새창을 띄웁니다.

    ajax를 썻다면 이렇게 새창을 두개씩이나 띄울 필요가 없었을텐데 ^^;; request를 보낼려면 어쩔수가 없군요.

    여튼 새창으로 페이지를 이동했으니 또 컨트롤러가 받아 적절한 Command를 실행시켰겠죠?

     

    - Controller

    case "/requestAuthEmail.four":
    	command = new AuthEmailRequestCommand();
    	command.execute(request, response);
    	viewPage = "requestAuthEmail.jsp";
    	break;

     

    - AuthEmailRequestCommand

    public class AuthEmailRequestCommand implements Command{
    
    	@Override
    	public void execute(HttpServletRequest request, HttpServletResponse response) {
    		String inputedEmail = request.getParameter("email");
    		
    		//인증코드 생성
    		String AuthenticationKey = authCodeMaker();
    		
    		// mail server 설정
    		String host = "smtp.gmail.com";
    		String user = ShareVar_login.hostID; // 자신의 구글 계정
    		String password = ShareVar_login.hostPW;// 자신의 구글 패스워드
    		
    		// 메일 받을 주소
    		String to_email = inputedEmail;
    		System.out.println("inputedEmail : " + inputedEmail);
    
    		// SMTP 서버 정보를 설정한다.
    		Properties prop = System.getProperties();
    		prop.put("mail.smtp.host", host);
    		//google - TLS : 587, SSL: 465
    		prop.put("mail.smtp.port", 465);
    		prop.put("mail.smtp.starttls.enable", "true");
    		prop.put("mail.smtp.auth", "true");
    		prop.put("mail.smtp.ssl.enable", "true");
    		prop.put("mail.smtp.ssl.trust", "smtp.gmail.com");
    		prop.put("mail.debug", "true");
            
    		Session session = Session.getDefaultInstance(prop, new javax.mail.Authenticator() {
    			protected PasswordAuthentication getPasswordAuthentication() {
    				return new PasswordAuthentication(user, password);
    			}
    		});
    		MimeMessage msg = new MimeMessage(session);
    		
    		// email 전송
    		try {
    			msg.setFrom(new InternetAddress(user));
    			msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to_email));
    
    			// 메일 제목
    			msg.setSubject("안녕하세요. 너공나공의 인증메일입니다.", "UTF-8");
    			// 메일 내용
    			msg.setText("인증 번호 :" + AuthenticationKey );
    
    			Transport.send(msg);
    			System.out.println("이메일 전송 : " + AuthenticationKey);
    			ShareVar_login sv = ShareVar_login.getInstance();
    			sv.authEamilCode = AuthenticationKey;
    
    		} catch (AddressException e) { 
    			// TODO Auto-generated catch block 
    			e.printStackTrace(); 
    		} catch (MessagingException e) { 
    				// TODO Auto-generated catch block 
    				e.printStackTrace(); 
    		}
    	}
        
        public String authCodeMaker() {
        	//...
        }
    }

     

    //...
    
    // 인증 번호 생성기
    	public String authCodeMaker() {
    		String authCode = null;
    		
    		StringBuffer temp = new StringBuffer();
    		Random rnd = new Random();
    		for (int i = 0; i < 10; i++) {
    			int rIndex = rnd.nextInt(3);
    			switch (rIndex) {
    			case 0:
    				// a-z
    				temp.append((char) ((int) (rnd.nextInt(26)) + 97));
    				break;
    			case 1:
    				// A-Z
    				temp.append((char) ((int) (rnd.nextInt(26)) + 65));
    				break;
    			case 2:
    				// 0-9
    				temp.append((rnd.nextInt(10)));
    				break;
    			}
    		}
    		
    		authCode = temp.toString();
    		System.out.println(authCode);
    		
    		return authCode;
    	}
    }

    Properties : SMTP서버 정보를 설정

    PasswordAuthentication : Host의 계정정보 저장

    Session : Properties와 PasswordAuthentication를 저장 및 유지

    MimeMessage : session에 저장된 정보를 바탕으로 내용을 추가해 메일을 구성합니다.

    Transport.send(MimeMessage) : 최종적으로 메일을 전송합니다.

     

     ShareVar_login?

    클래스는 제 구글계정의 이메일과 비밀번호를 static변수로 가지고 있는 클래스입니다.

    대신에 직접 입력하시거나 별도 클래스를 생성해서 관리하시면 되겠습니다.

     

    예외처리

    catch구문안에서 작업해주시면 됩니다.

     

     authCodeMaker()

     영문 대문자-소문자, 숫자로 이루어진 랜덤한 10자리의 인증코드를 만들어줍니다.

    그리고 이메일 발송이 성공하게 되면 해당 인증코드를 ShareVar_login에 저장해 세션대신 사용합니다.

    ShareVar_login클래스는 구글계정 빼고는 싱글톤으로 구성되 있어서 getInstance를 사용해 호출했습니다.

     

     

    위의 메일 발송이 끝나게 되면 Controller에서 requestAuthEmail.jsp로 이동합니다.

    <%@page import="com.ysms.common.ShareVar_login"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    
    <%
    String authCode = ShareVar_login.authEamilCode;
    %>
    
    <script type="text/javascript">
    
    	alert("인증메일 전송 완료");
    	self.close();
    	opener.close();
    
    </script>
    <body>
    </body>
    </html>

     상당히 심플하죠...?

    제가 이메일 발송 성공/실패에 따른 예외처리를 작성하지 않아서 그렇습니다....하하;;;

    catch 구문에서 실패했다는 정보를 request에 담아 보내고 jsp페이지에서 분기처리를 꼭 하시길 바랍니다...!ㅜㅜ

    여튼 새창에서 작업은 이렇게 끝나게 됩니다.

     

     

    그리고 돌고돌아 멀리 왔지만 다시 signUpForm.jsp로 돌아가보면...

    <form name="signUpForm" action="signUpInput.four" method="post" enctype="multipart/form-data" accept-charset="UTF-8">
    <table class="table" style="margin-left: auto; margin-right: auto;">
    
    ...
    
    <tr>
    	<th>이메일</th>
    	<td><input type="text" name="email" id="inputEmailForm"  maxlength="30">
    	<button onclick="emailAuthentication()" id="eamilAuthBtn" type="button" class="btnChk">인증 메일 보내기</button></td>
    </tr>
    <tr>
    	<th rowspan="2"><a>인증번호 입력</a></th>
    	<td colspan="2"><input type="text" name="authCode" id="inputAuthCode"  maxlength="10" disabled="disabled">
    	<button onclick="authCodeCheck()" id="authCodeCheckBtn" type="button" disabled="disabled" class="btnChk">인증</button>
    	<input type="hidden" name="authPass" id="authPass" value="false">
    </td>
    </tr>	
    
    ...
    
    </table>

    <input type="hidden" name="authPass" id="authPass" value="false">

    • 이메일 인증까지 끝나면 value = true
    • 최종적으로 회원가입시 이메일 인증이 됬나 안됬나를 체크

     

    이제 인증번호를 누르고 인증하기 버튼을 누를 차례죠...? 누르면 authCodeCheck()를 호출합니다.

    function authCodeCheck(){
    	var url = "authCodeCheck.jsp?inputedCode=" + document.signUpForm.authCode.value;
    	open(url, "confirm",
    			"toolbar=no, location=no,menubar=no,scrollbars=no,resizable=no,width=300,height=200");
    }

     죄송스럽게도 또 새 창 입니다. 하하... 그때의 저에게 Ajax좀 쓰지그랬냐~~!! 라고 하고 싶네요...

    하지만 정말 마지막 단계입니다! 새 url로 새창으로 이동했으니 Controller가 알맞게 Command를 호출해 줫겠죠?

    아니요, 다이렉트로 jsp에다가 get방식으로 입력한 코드를 전송했네요!

     

     authCodeCheck.jsp

    <%@page import="com.ysms.common.ShareVar_login"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    
    <%
    String result = "false";
    	String authCode = ShareVar_login.authEamilCode;
    	String inputedCode = request.getParameter("inputedCode");
    	
    	if(authCode.equals(inputedCode)){
    		result = "true";
    	}
    %>
    
    <script type="text/javascript">
    	var result = "true";
    	var inputedCode = "<%=inputedCode%>";
    	
    	if (inputedCode == ""){
    		alert("인증번호가 올바르지 않습니다.");
    		opener.document.getElementById("authPass").value = "false";
    		self.close();
    	}
    	if(<%=result%> == true){
    		alert("인증이 완료되었습니다.");
    		opener.document.getElementById("authPass").value = "true";
    		console.log("<%=result%>");
    		opener.document.signUpForm.inputEmailForm.readOnly = true; 
    		opener.document.signUpForm.eamilAuthBtn.readOnly = true;
    		opener.document.signUpForm.authCodeCheckBtn.disabled = true;
    		opener.document.signUpForm.inputAuthCode.disabled = true;
    		self.close();
    	} else {
    		alert("인증번호가 올바르지 않습니다.");
    		opener.document.getElementById("authPass").value = "false";
    		self.close();
    	}
    
    </script>
    <body>
    
    </body>
    </html>

    컨트롤러를 거치지 않고 다이렉트로 이동한 이유

    •  jsp에선 ShareVar_login에 접근할 수 있으니 컨트롤러를 패스하고 다이렉트로 이동

    지금 생각해보면 인증코드를 get방식으로 보내는건 옳지 않다고 생각이 드네요. 이 글 보시고 도전하신다면 꼭 이렇게 하지 마시길.

    post로 값을 전송하는다른 방법

    1. 부모창의 html body 구석에 form을 만들고 안에 hidden타입의 input 태그를 만든다.
    2. 인증코드를 자식창이 생성하면 부모창의 히든태그 안에 값을 입력한다.
    3. 인증 버튼을 누르면 java script가 해당 폼을 submit한다.

     

     

    제일 좋은방법

    • ajax 씁시다.

     

     

     이렇게 이메일 인증 구현이 끝이 났구요,

    만약 끝까지 읽어주셨다면 부족한 글 끝까지 읽어주셔서 감사합니다.

    도움이 됬다면 더할나위 없이 뿌듯하겠네요 ^^


    JSP 회원가입시 이메일 인증 절차 구현- (1) 시작하며
    JSP 회원가입시 이메일 인증 절차 - (2) 이메일 정규식 검증
    JSP 회원가입시 이메일 인증 절차 - (3) 이메일 중복 확인
    JSP 회원가입시 이메일 인증 절차 - (4) 인증 이메일 전송

    반응형
    저작자표시 (새창열림)

    'IDE & Framework > 분류중' 카테고리의 다른 글

    JSP 이미지CRUD가 가능한 페이징된 게시판 구현  (0) 2021.05.31
    JSP 페이징된 게시판 만들기  (0) 2021.05.30
    JSP 회원가입시 이메일 인증 절차 - (3/4) 이메일 중복 확인  (0) 2021.05.30
    JSP 회원가입시 이메일 인증 절차 - (2/4) 이메일 정규식 검증  (0) 2021.05.29
    JSP 회원가입시 이메일 인증 절차 구현- (1/4) 시작하며  (0) 2021.05.29
      'IDE & Framework/분류중' 카테고리의 다른 글
      • JSP 이미지CRUD가 가능한 페이징된 게시판 구현
      • JSP 페이징된 게시판 만들기
      • JSP 회원가입시 이메일 인증 절차 - (3/4) 이메일 중복 확인
      • JSP 회원가입시 이메일 인증 절차 - (2/4) 이메일 정규식 검증
      Greensky0026
      Greensky0026
      점이 모여 선이 된다. 내 삽질도 언젠간 거대한 지하 도시가 되겠지!

      티스토리툴바