안경잡이개발자

728x90
반응형

  이번 시간은 JSP 강의평가(Lecture Evaluation) 웹 사이트 개발하기의 여섯 번째 시간입니다. 지난 시간에는 회원 데이터를 모델링하는 시간을 가져보았습니다. 이번 시간에는 모델링한 DTO, DAO를 이용하여 실제로 회원가입을 수행하고, 이메일을 전송하는 기능을 구현해보도록 하겠습니다. 기본적으로 이러한 기능을 위해서는 두 가지 유틸리티가 필요합니다. 하나는 회원가입 및 이메일 인증에 사용할 해시 데이터를 생성할 수 있는 SHA256 클래스이고, 다른 하나는 사용자에게 SMTP를 이용해 이메일 인증 메시지를 전송하는 이메일 전송 관련 Gmail 클래스입니다. 바로 다음과 같이 util 패키지를 생성해서 두 개의 클래스를 만들어주시면 됩니다.



  이후에 SMTP를 이용해 메일을 전송하기 위해서는 몇 가지 추가적인 외부 라이브러리가 필요합니다. 첫 번째는 Mail 라이브러리이며 다른 하나는 Activation 클래스입니다. 라이브러리가 없으신 분들은 다음의 링크에서 받아서 이용하시면 됩니다.


  ▶ Mail 라이브러리 다운로드 사이트: http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-eeplat-419426.html#javamail-1.4.7-oth-JPR


  ▶ Activation 라이브러리 다운로드 사이트: http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html#jaf-1.1-fr-oth-JPR


  위 사이트로 접속하셔서 각각 javamail.zip과 jaf.zip를 다운로드 받으신 뒤에 압축을 푸셔서 라이브러리를 찾아서 다음과 같이 WEB-INF 폴더 내부의 lib 폴더에 넣어주시면 됩니다.



  이제 한 번 우리의 util 패키지 내에 있는 클래스들을 작성해보도록 하겠습니다.


  ▶ SHA256.java


package util;


import java.security.MessageDigest;


public class SHA256 {


public static String getSHA256(String input) {

StringBuffer result = new StringBuffer();

try {

MessageDigest digest = MessageDigest.getInstance("SHA-256");

byte[] salt = "Hello! This is Salt.".getBytes();

digest.reset();

digest.update(salt);

byte[] chars = digest.digest(input.getBytes("UTF-8"));

for(int i = 0; i < chars.length; i++) {

String hex = Integer.toHexString(0xff & chars[i]);

if(hex.length() == 1) result.append('0');

result.append(hex);

}

} catch (Exception e) {

e.printStackTrace();

}

return result.toString();

}

}


  위 소스코드를 보시면 솔트(Salt) 부분이 들어가있는 것을 알 수 있습니다. 해시 데이터를 생성할 때 악의적인 목적을 가진 공격자가 원래의 데이터를 파악하기 더욱 어렵게 만들어 줄 수 있습니다.


  ▶ Gmail.java


package util;


import javax.mail.Authenticator;

import javax.mail.PasswordAuthentication;


public class Gmail extends Authenticator {


    @Override

    protected PasswordAuthentication getPasswordAuthentication() {

        return new PasswordAuthentication("아이디","비밀번호");

    }

    

}


  SMTP에서 인증을 위한 부분을 위와 같이 클래스에서 작성할 수 있습니다. 저는 구글 이메일(G-Mail)을 사용해보도록 하겠습니다. 자신의 구글 계정 중에서 이메일을 사용할 수 있는 계정을 입력하시면 됩니다. 또한 기본적으로 구글 계정은 '계정' 설정에서 '보안 수준이 낮은 앱'에 대한 접근 권한이 설정되어야 합니다.



  이제 다음과 같이 userRegisterAction.jsp, emailCheckAction.jsp, emailSendAction.jsp 세 가지를 만들어줍니다.



▶ userRegisterAction.jsp: 회원가입을 처리합니다. 사용자 정보를 데이터베이스에 등록한 이후에, 자동으로 사용자의 이메일로 이메일을 전송하고 인증을 기다립니다.


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ page import="user.UserDTO"%>

<%@ page import="user.UserDAO"%>

<%@ page import="util.SHA256"%>

<%@ page import="java.io.PrintWriter"%>

<%

request.setCharacterEncoding("UTF-8");

String userID = null;

String userPassword = null;

String userEmail = null;

if(request.getParameter("userID") != null) {

userID = (String) request.getParameter("userID");

}

if(request.getParameter("userPassword") != null) {

userPassword = (String) request.getParameter("userPassword");

}

if(request.getParameter("userEmail") != null) {

userEmail = (String) request.getParameter("userEmail");

}

if (userID == null || userPassword == null || userEmail == null) {

PrintWriter script = response.getWriter();

script.println("<script>");

script.println("alert('입력이 안 된 사항이 있습니다.');");

script.println("history.back();");

script.println("</script>");

script.close();

} else {

UserDAO userDAO = new UserDAO();

int result = userDAO.join(new UserDTO(userID, userPassword, userEmail, SHA256.getSHA256(userEmail), false));

if (result == -1) {

PrintWriter script = response.getWriter();

script.println("<script>");

script.println("alert('이미 존재하는 아이디입니다.');");

script.println("history.back();");

script.println("</script>");

script.close();

} else {

session.setAttribute("userID", userID);

PrintWriter script = response.getWriter();

script.println("<script>");

script.println("location.href = 'emailSendAction.jsp';");

script.println("</script>");

script.close();

}

}

%>


▶ emailSendAction.jsp: 이메일 인증 메시지를 이메일을 통해 전송합니다.


<%@page import="javax.mail.Transport"%>

<%@page import="javax.mail.Message"%>

<%@page import="javax.mail.Address"%>

<%@page import="javax.mail.internet.InternetAddress"%>

<%@page import="javax.mail.internet.MimeMessage"%>

<%@page import="javax.mail.Session"%>

<%@page import="javax.mail.Authenticator"%>

<%@page import="java.util.Properties"%>

<%@page import="java.io.PrintWriter"%>

<%@page import="user.UserDAO"%>

<%@page import="util.SHA256"%>

<%@page import="util.Gmail"%>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%

UserDAO userDAO = new UserDAO();

String userID = null;

if(session.getAttribute("userID") != null) {

userID = (String) session.getAttribute("userID");

}

if(userID == null) {

PrintWriter script = response.getWriter();

script.println("<script>");

script.println("alert('로그인을 해주세요.');");

script.println("location.href = 'userLogin.jsp'");

script.println("</script>");

script.close();

return;

}

boolean emailChecked = userDAO.getUserEmailChecked(userID);

if(emailChecked == true) {

PrintWriter script = response.getWriter();

script.println("<script>");

script.println("alert('이미 인증 된 회원입니다.');");

script.println("location.href = 'index.jsp'");

script.println("</script>");

script.close();

return;

}

// 사용자에게 보낼 메시지를 기입합니다.

String host = "http://localhost:8080/Lecture_Evaluation/";

String from = "이메일 아이디";

String to = userDAO.getUserEmail(userID);

String subject = "강의평가를 위한 이메일 확인 메일입니다.";

String content = "다음 링크에 접속하여 이메일 확인을 진행하세요." +

"<a href='" + host + "emailCheckAction.jsp?code=" + new SHA256().getSHA256(to) + "'>이메일 인증하기</a>";

// SMTP에 접속하기 위한 정보를 기입합니다.

Properties p = new Properties();

p.put("mail.smtp.user", from);

p.put("mail.smtp.host", "smtp.googlemail.com");

p.put("mail.smtp.port", "465");

p.put("mail.smtp.starttls.enable", "true");

p.put("mail.smtp.auth", "true");

p.put("mail.smtp.debug", "true");

p.put("mail.smtp.socketFactory.port", "465");

p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");

p.put("mail.smtp.socketFactory.fallback", "false");

 

try{

    Authenticator auth = new Gmail();

    Session ses = Session.getInstance(p, auth);

    ses.setDebug(true);

    MimeMessage msg = new MimeMessage(ses); 

    msg.setSubject(subject);

    Address fromAddr = new InternetAddress(from);

    msg.setFrom(fromAddr);

    Address toAddr = new InternetAddress(to);

    msg.addRecipient(Message.RecipientType.TO, toAddr);

    msg.setContent(content, "text/html;charset=UTF-8");

    Transport.send(msg);

} catch(Exception e){

    e.printStackTrace();

PrintWriter script = response.getWriter();

script.println("<script>");

script.println("alert('오류가 발생했습니다..');");

script.println("history.back();");

script.println("</script>");

script.close();

    return;

}

%>

<!doctype html>

<html>

  <head>

    <title>강의평가 웹 사이트</title>

    <meta charset="utf-8">

    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- 부트스트랩 CSS 추가하기 -->

    <link rel="stylesheet" href="./css/bootstrap.min.css">

    <!-- 커스텀 CSS 추가하기 -->

    <link rel="stylesheet" href="./css/custom.css">

  </head>

  <body>

    <nav class="navbar navbar-expand-lg navbar-light bg-light">

      <a class="navbar-brand" href="index.jsp">강의평가 웹 사이트</a>

      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar">

        <span class="navbar-toggler-icon"></span>

      </button>

      <div class="collapse navbar-collapse" id="navbar">

        <ul class="navbar-nav mr-auto">

          <li class="nav-item active">

            <a class="nav-link" href="index.jsp">메인</a>

          </li>

          <li class="nav-item dropdown">

            <a class="nav-link dropdown-toggle" id="dropdown" data-toggle="dropdown">

              회원 관리

            </a>

            <div class="dropdown-menu" aria-labelledby="dropdown">

              <a class="dropdown-item" href="userLogin.jsp">로그인</a>

            </div>

          </li>

        </ul>

        <form action="./index.jsp" method="get" class="form-inline my-2 my-lg-0">

          <input type="text" name="search" class="form-control mr-sm-2" placeholder="내용을 입력하세요.">

          <button class="btn btn-outline-success my-2 my-sm-0" type="submit">검색</button>

        </form>

      </div>

    </nav>

<div class="container">

    <div class="alert alert-success mt-4" role="alert">

  이메일 주소 인증 메일이 전송되었습니다. 이메일에 들어가셔서 인증해주세요.

</div>

    </div>

    <footer class="bg-dark mt-4 p-5 text-center" style="color: #FFFFFF;">

      Copyright ⓒ 2018 나동빈 All Rights Reserved.

    </footer>

    <!-- 제이쿼리 자바스크립트 추가하기 -->

    <script src="./js/jquery.min.js"></script>

    <!-- Popper 자바스크립트 추가하기 -->

    <script src="./js/popper.min.js"></script>

    <!-- 부트스트랩 자바스크립트 추가하기 -->

    <script src="./js/bootstrap.min.js"></script>

  </body>

</html>


▶ emailCheckAction.jsp: 사용자가 이메일 인증을 하게 되면 그에 대한 정보를 처리하는 페이지입니다.


<%@page import="java.io.PrintWriter"%>

<%@page import="util.SHA256"%>

<%@page import="user.UserDAO"%>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%

request.setCharacterEncoding("UTF-8");

String code = request.getParameter("code");

UserDAO userDAO = new UserDAO();

String userID = null;

if(session.getAttribute("userID") != null) {

userID = (String) session.getAttribute("userID");

}

if(userID == null) {

PrintWriter script = response.getWriter();

script.println("<script>");

script.println("alert('로그인을 해주세요.');");

script.println("location.href = 'userLogin.jsp'");

script.println("</script>");

script.close();

return;

}

String userEmail = userDAO.getUserEmail(userID);

boolean rightCode = (new SHA256().getSHA256(userEmail).equals(code)) ? true : false;

if(rightCode == true) {

userDAO.setUserEmailChecked(userID);

PrintWriter script = response.getWriter();

script.println("<script>");

script.println("alert('인증에 성공했습니다.');");

script.println("location.href = 'index.jsp'");

script.println("</script>");

script.close();

return;

} else {

PrintWriter script = response.getWriter();

script.println("<script>");

script.println("alert('유효하지 않은 코드입니다.');");

script.println("location.href = 'index.jsp'");

script.println("</script>");

script.close();

return;

}

%>


  이제 한 번 테스트를 해봅시다.



  먼저 위와 같이 회원가입을 해주겠습니다.



이후에 위와 같이 회원가입 된 정보를 확인합시다.



이후에 이메일 주소 인증 메일이 전송되었다는 메시지가 나오네요.



  이제 이메일 함으로 이동해보시면 위와 같이 인증 메일이 온 것을 확인할 수 있습니다.



  링크를 타고 이동하면 위와 같이 인증이 완료되어 메인 페이지가 등장합니다.



이후에 위와 같이 데이터베이스에서 사용자 정보를 확인하면 'userEmailChecked' 속성의 값이 1(True)로 바뀌어있는 것을 확인할 수 있습니다.

728x90
반응형

Comment +19

  • 살길바라냐 2018.06.21 08:57

    인프런에서 배운 userRegisterAction.jsp에서 codeunreachable 뜨네요 인프런과 여기 홈피에서 코딩이 많이 다른데 어디껄 따르면 되나요??

  • 2018.06.26 15:31

    비밀댓글입니다

  • 초보입니다. 2018.07.01 14:33

    org.apache.jasper.JasperException: Unable to compile class for JSP:

    An error occurred at line: [14] in the generated java file: [D:\Users\WH_Laptop\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\work\Catalina\localhost\Lecture_Evaluation\org\apache\jsp\userRegisterAction_jsp.java]
    Only a type can be imported. user.UserDTO resolves to a package

    An error occurred at line: [15] in the generated java file: [D:\Users\WH_Laptop\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\work\Catalina\localhost\Lecture_Evaluation\org\apache\jsp\userRegisterAction_jsp.java]
    Only a type can be imported. user.UserDAO resolves to a package

    An error occurred at line: [16] in the generated java file: [D:\Users\WH_Laptop\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\work\Catalina\localhost\Lecture_Evaluation\org\apache\jsp\userRegisterAction_jsp.java]
    Only a type can be imported. util.SHA256 resolves to a package

    An error occurred at line: [53] in the jsp file: [/userRegisterAction.jsp]
    UserDAO cannot be resolved to a type
    50:
    51: } else {
    52:
    53: UserDAO userDAO = new UserDAO();
    54:
    55: int result = userDAO.join(new UserDTO(userID, userPassword, userEmail, SHA256.getSHA256(userEmail), false));
    56:


    An error occurred at line: [53] in the jsp file: [/userRegisterAction.jsp]
    UserDAO cannot be resolved to a type
    50:
    51: } else {
    52:
    53: UserDAO userDAO = new UserDAO();
    54:
    55: int result = userDAO.join(new UserDTO(userID, userPassword, userEmail, SHA256.getSHA256(userEmail), false));
    56:


    An error occurred at line: [55] in the jsp file: [/userRegisterAction.jsp]
    UserDTO cannot be resolved to a type
    52:
    53: UserDAO userDAO = new UserDAO();
    54:
    55: int result = userDAO.join(new UserDTO(userID, userPassword, userEmail, SHA256.getSHA256(userEmail), false));
    56:
    57: if (result == -1) {
    58:


    An error occurred at line: [55] in the jsp file: [/userRegisterAction.jsp]
    SHA256 cannot be resolved
    52:
    53: UserDAO userDAO = new UserDAO();
    54:
    55: int result = userDAO.join(new UserDTO(userID, userPassword, userEmail, SHA256.getSHA256(userEmail), false));
    56:
    57: if (result == -1) {
    58:


    Stacktrace:
    org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:102)
    org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:212)
    org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:495)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:379)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:351)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:335)
    org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:595)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:368)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)


    인프런 강의를 보면서 실습 중인데여 404 에러가 떠야하는데 500에러가 뜨면서 이렇게 나옵니다.
    분명 다 맞게 썻는데 이러네요 혹시나 하고 복붙을 해봐도 안됩니다.

    아 그리고 mysql 설치할때 3306 포트가 안되서 3305로 했는데 여기서 영향이 생긴건가요?

  • 도와주세요.. 2018.11.12 15:37

    3일째 해결이 안되네요.. 부탁드립니다.
    에러 내용은 아래 에 첨부 하겠습니다.

    EBUG: setDebug: JavaMail version 1.4.7
    DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
    DEBUG SMTP: useEhlo true, useAuth true
    DEBUG SMTP: useEhlo true, useAuth true
    DEBUG SMTP: trying to connect to host "smtp.googlemail.com", port 465, isSSL false
    Could not connect to SMTP host: smtp.googlemail.com, port: 465
    javax.mail.MessagingException: Could not connect to SMTP host: smtp.googlemail.com, port: 465;
    nested exception is: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

  • 이상열 2018.12.09 02:30

    int result = userDAO.join(new userDTO(userID,userPassword,userEmail,SHA256.getSHA256(userEmail),false));
    이부분이 계속 오류가 나는거로 표시가 됩니다.

  • mrblack 2019.03.03 21:47

    안녕하세요?
    위 강의 따라 하던중 회원 가입을 하면 "이미 존재하는 아이디" 라고 나옵니다.
    데이터베이스에는 아무 내용도 없습니다.
    심지어 아무것도 입력하지 않고 회원가입 눌러도 "이미 존재하는 아이디" 라고 나옵니다.
    userRegisterAction.jsp에서 email 처리부분을 주석 처리하고 아무것도 입력하지 않고 회원가입 버튼 누르면 그제서야 "입력이 안된 사항이 있습니다"라고 나옵니다.

    if(request.getParameter("userEmail") != null) {
    userEmail = (String) request.getParameter("userEmail");
    }

    이부분이 계속 처리가 안되는것 같은데요.. 원인을 알 수 있을까요?

  • 2019.05.07 23:16

    비밀댓글입니다

  • 2019.06.04 07:35

    비밀댓글입니다

  • indiana 2019.07.14 16:33

    안녕하세요! 강의 잘보면서 따라하고 있는데,
    궁금한게 있어서요..
    제가 메일을 보내면 관리자 메일로도 회원가입한 사람 메일에 간 인증메일이 똑같이 보내지는데
    원래 그런건가요 아니면 제가 어디서 실수한거일까요..?

  • 2019.08.05 14:58

    비밀댓글입니다

  • 1234 2019.08.05 14:59

    버2ㅣㄷ

  • 지지 2019.09.21 17:04

    int result = userDAO.join(new UserDTO(userID, userPassword, userEmail, SHA256.getSHA256(userEmail),false));

    이 구문에서 500에러 발생하는데 어떻게 해결하나요 ?

  • 안녕하세요 2019.10.17 23:26

    535-5.7.8 Username and Password not accepted. Learn more at
    535 5.7.8 https://support.google.com/mail/?p=BadCredentials v2sm2787590pgf.39 - gsmtp
    오류가 조회되는데요 보안설정에서 낮은 수준액세스 허용도 해보았고 계정의 아이디 비번 다 체크해도
    이상이없는데 위와같이 오류가 조회됩니다. 원인이 무엇인지 찾지를 못하고 있습니다.

  • 개발꿈나무 2019.11.13 22:07

    도메인과 서버를 샀는데요 도메인에 올렸을때는 왜 이메일 전송이 안될까요? localhost에서는 이메일 전송이 됩니다.

  • 2019.12.09 18:17

    org.apache.jasper.JasperException: 행 [57]에서 [userRegisterAction.jsp]을(를) 처리하는 중 예외 발생


    55: UserDAO userDAO = new UserDAO();
    56:
    57: int result = userDAO.join(new UserDTO(userID, userPassword, userEmail, SHA256.getSHA256(userEmail), false));
    58:
    59: if (result == -1) {

    오류가나오는대 무엇떄문일까요

  • 문상우 2020.02.21 15:30

    jsp 공부중인 학생입니다.

    DEBUG: setDebug: JavaMail version 1.4.7
    DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
    DEBUG SMTP: useEhlo true, useAuth true
    DEBUG SMTP: useEhlo true, useAuth true
    DEBUG SMTP: trying to connect to host "smtp.gmail.co.kr", port 465, isSSL true
    javax.mail.MessagingException: Unknown SMTP host: smtp.gmail.co.kr;
    nested exception is:

    포트 번호도 바꾸어 보고 했지만 게속 해서 오류가 없어 지지 않아서 ...
    마땅히 오류해결할 방법을 찾지 못해서요 ..

  • 아니진자 2020.10.09 19:37

    관리자의 승인을 기다리고 있는 댓글입니다