전 포스팅에선 이메일 인증절차까지 완료하였죠? 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로 값을 전송하는다른 방법
- 부모창의 html body 구석에 form을 만들고 안에 hidden타입의 input 태그를 만든다.
- 인증코드를 자식창이 생성하면 부모창의 히든태그 안에 값을 입력한다.
- 인증 버튼을 누르면 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 |