관리 메뉴

공부한것들을 정리하는 블로그 입니다.

gmail로 email 인증번호 보내기(비밀번호 찾기 기능/ 회원가입시 이메일 인증/smtp) 본문

JAVA/공부

gmail로 email 인증번호 보내기(비밀번호 찾기 기능/ 회원가입시 이메일 인증/smtp)

호 두 2019. 12. 13. 23:08
반응형

 

** gmail로 email을 인증하는 여러가지 경우를 모두 다루어보기 위해 포스팅하였습니다. (smtp)

 

 

1. 사전작업 - 구글 보안정책 : 구글 보안정책 관련하여 본인의 이메일 계정에 대해 몇가지 조치가 필요합니다.

    - POP/IMAP 활성화

    - 2단계 인증 활성화 (이건 안해도 됬던걸로 기억합니다. 그냥 보안절차상 넣었습니다.)

    - 계정에 대한 "보안수준이 낮은 앱의 액세스를 허용" 하고, 실습종료 후 원복 (다시 비허용)

2. 스프링부트에서 gmail인증 api 사용법 (내장톰캣 사용 - 톰캣 다운로드 필요x)

    - 설정파일(properties 파일)을 통한 사용

3. SpringMVC에서 gmail인증 api 사용법

    - 설정파일(xml 파일)을 통한 사용

4. JSP에서 gmail인증 api 사용법

 

 

 

 

1. 사전작업 - 구글 보안정책 : 구글 보안정책 관련하여 본인의 이메일 계정에 대해 몇가지 조치가 필요합니다.

 

- POP/IMAP 활성화

 

 

https://support.google.com/mail/answer/7104828?hl=ko

상기 링크로 이동하여 시키는대로 먼저 POP 설정을 번경해줍니다.

  • 컴퓨터에서 Gmail을 엽니다. 
  • 오른쪽 상단에서 설정 설정을 클릭합니다. 
  • 환경설정을 클릭합니다. 
  • 전달 및 POP/IMAP 탭을 클릭합니다. 
  • 'POP 다운로드' 섹션에서 모든 메일에 POP 사용하기 또는 지금부터 수신되는 메일에만 POP 사용하기를 선택합니다. 
  • 페이지 하단에서 변경사항 저장을 클릭합니다.

 

 

 

https://support.google.com/mail/answer/7126229?hl=ko

이번에는 상기 링크로 이동하여 IMAP를 설정해 줍니다

 

 

- 2단계 인증 활성화 (이건 안해도 됬던걸로 기억합니다. 그냥 보안절차상 넣었습니다.)

 

 

 

이부분은 따로 설정해주지 않아도 상관 없는 것으로 기억합니다. 혹시 진행하시다가 보안관련해서 문제가 발생하신다면 설정해주시면 됩니다.

https://support.google.com/accounts/answer/185839?co=GENIE.Platform%3DAndroid&hl=ko

 

 

- 계정에 대한 "보안수준이 낮은 앱의 액세스를 허용" 하고, 실습종료 후 원복 (다시 비허용)

아래 링크에서 "보안수준이 낮은 앱의 액세스를 허용"해주셔야 합니다.

https://myaccount.google.com/lesssecureapps

 

 

 

만약 "보안수준이 낮은 앱의 액세스를 허용" 하지 않는다면, 실습진행중에 아래와 같은 에러가 발생 할 것입니다.

 

 

 

 

 

 

에러내용 : 
javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at 
535 5.7.8  https://support.google.com/mail/?p=BadCredentials j21sm3515904pfe.175 - gsmtp

 

해당 에러가 발생하는 지점은, 실습을 진행하면서 한번 더 다루도록 하겠습니다.

보안문제가 걱정되는 개인사용자의 경우, 실습 종료 후 "보안수준이 낮은 앱의 액세스를 허용"을 다시 원복해놓으시면 됩니다.

 

 

여기까지 완료하셨으면 이제 본격적으로 프로젝트 실습을 진행하도록 하겠습니다.

 

 

 

 

2. 스프링부트를 통한 gmail인증 api 사용법 (내장톰캣 사용 - 톰캣 다운로드 필요x)

 

- pom.xml에 javax mail 관련 dependency 추가

		<dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-starter-mail</artifactId>
		</dependency>

 

- application.properties 에 smpt 설정 추가

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=발신인메일@gmail.com   ex) hodoo.tistory@gmail.com
spring.mail.password=발신인메일의 비밀번호   ex) password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

 

- kr.com.cyh.email 경로에 EmailApplication.java 추가

package kr.com.cyh.email;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class EmailApplication {

	public static void main(String[] args) {
		SpringApplication.run(EmailApplication.class, args);
	}

}

 

- kr.com.cyh.email.controller 경로에 EmailController.java 추가

package kr.com.cyh.email.controller;

import java.util.Map;

import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class EmailController {

	@Autowired
	private JavaMailSender mailSender;
	
	@RequestMapping(value = "/email")
	public String emailPage() {
		
		return "email";
	}
	
	@RequestMapping(value="/searchPw.do", method=RequestMethod.GET)
    public ModelAndView sendEmailAction (@RequestParam Map<String, Object> paramMap, ModelMap model, ModelAndView mv) throws Exception {
 
        String USERNAME = (String) paramMap.get("username");
        String EMAIL = (String) paramMap.get("email");
        String PASSWORD = "1111111111";
             
        try {
            MimeMessage msg = mailSender.createMimeMessage();
            MimeMessageHelper messageHelper = new MimeMessageHelper(msg, true, "UTF-8");
             
            messageHelper.setSubject(USERNAME+"님 비밀번호 찾기 메일입니다.");
            messageHelper.setText("비밀번호는 "+PASSWORD+" 입니다.");
            messageHelper.setTo(EMAIL);
            msg.setRecipients(MimeMessage.RecipientType.TO , InternetAddress.parse(EMAIL));
            mailSender.send(msg);
             
        }catch(MessagingException e) {
            System.out.println("MessagingException");
            e.printStackTrace();
        }
//        mv.setViewName("redirect:/emailSuccess");
        mv.setViewName("emailSuccess");
        return mv;
    }

}

 

이메일발송 기능이 완료되었습니다. 여기까지 진행하셨다면 junit을 통해 해당 메서드의 단위테스트가 진행 가능합니다.

이제 화면에 대한 설정을 추가해보도록 하겠습니다.

 

- jsp를 사용해주기 위한 설정을 pom.xml에 추가

		<dependency>
		    <groupId>javax.servlet</groupId>
		    <artifactId>jstl</artifactId>
		</dependency>
		 
		<dependency>
		    <groupId>org.apache.tomcat.embed</groupId>
		    <artifactId>tomcat-embed-jasper</artifactId>
		</dependency>

 

- application.properties 에 jsp 설정 추가

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

 

 

 

 

- 지정해준 경로에 email.jsp 추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>

<body>
    <div>
        <form action="searchPw.do" method="get">
            <h2>비밀번호 찾기</h2>
            <p>
                아래 이메일주소를 입력하시면,<br> 입력하신 이메일로 새암호를 보내드립니다<br>
                <br>
            <div>
                <input type="text" name="username" placeholder="이름">
            </div>
            <div>
                <input type="text" name="email" placeholder="이메일주소">
                <p>'@'포함한 이메일주소를 정확히 입력해주세요.</p>
            </div>
 
            <div>
                <button type="submit">비밀번호찾기</button>
            </div>
        </form>
    </div>
</body>


</html>

 

- 지정해준 경로에 emailSuccess.jsp 추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>

<body>
    <h1>이메일이 정상적으로 발송되었습니다.</h1>
</body>

</html>

 

 

이로써 화면과 기능이 모두 완료되었습니다.

브라우저를 통한 실습으로 마무리하도록 하겠습니다.

 

 

 

 

- 에러가 발생하는 경우

 

 

username 과 email 입력 후 "비밀번호 찾기" 버튼을 클릭하시면 searchPw.do 가 실행됩니다.

간혹 여기서 아래와 같이 에러가 출력되는 분들이 계신데요.

 

 

 

 

 

 

 

에러내용 : 
javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at 
535 5.7.8  https://support.google.com/mail/?p=BadCredentials j21sm3515904pfe.175 - gsmtp

 

해당 에러가 발생하는 경우는 크게 2가지로

1. 발신자로 지정한 이메일의 username / password 를 잘못 입력 한 경우

2. 구글의 보안정책 : 보안수준이 낮은 앱의 엑세스를 '사용안함' 한 경우

입니다.

 

 

여기서 [ 2. 구글의 보안정책 : 보안수준이 낮은 앱의 엑세스를 '사용안함' 한 경우 ] 를 해결하려면

아래 링크에서 "보안수준이 낮은 앱의 액세스를 허용"해주셔야 합니다.

https://myaccount.google.com/lesssecureapps

 

 

 

 

 

 

해결완료

 

 

 

 

3. Spring MVC를 통한 gmail인증 api 사용법 (dynamic web project - 외장톰캣 사용 - 톰캣 다운로드 필요)

 

- pom.xml에 javax mail 관련 dependency 추가

        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>

 

- web.xml 에 smpt 설정을 위한 리스너 및 설정파일(xml파일) 추가

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/*context.xml</param-value>
	</context-param>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

 

 

 

- email-context.xml 에 gmail smtp 설정 추가

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
	
	<context:component-scan base-package="kr.com.cyh.email" />
	
	<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="smtp.gmail.com" />
        <property name="port" value="587" />
        <property name="username" value="발신인 이메일@gmail.com" />
        <property name="password" value="발신인 이메일의 비밀번호" />
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.starttls.enable">true</prop>
            </props>
        </property>
    </bean>
    
</beans>

 

- servlet-context 에서 지정해놓은 경로에 view(jsp 파일) 추가

 

 

 

 

- 만약 따로 설정해놓지 않았을 경우, view(jsp 파일)을 /webapp/ 하위로 이동시킨 후, 브라우저에서 .jsp까지 포함해서 입력하시면 됩니다.

 

 

- email.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>

<body>
    <div>
        <form action="searchPw.do" method="get">
            <h2>비밀번호 찾기</h2>
            <p>
                아래 이메일주소를 입력하시면,<br> 입력하신 이메일로 새암호를 보내드립니다<br>
                <br>
            <div>
                <input type="text" name="username" placeholder="이름">
            </div>
            <div>
                <input type="text" name="email" placeholder="이메일주소">
                <p>'@'포함한 이메일주소를 정확히 입력해주세요.</p>
            </div>
 
            <div>
                <button type="submit">비밀번호찾기</button>
            </div>
        </form>
    </div>
</body>


</html>

- emailSuccess.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>

<body>
    <h1>이메일이 정상적으로 발송되었습니다.</h1>
</body>

</html>

 

- kr.com.cyh.email.controller 경로에 EmailController.java 추가

package kr.com.cyh.email.controller;

import java.util.Map;

import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class EmailController {

	@Autowired
	private JavaMailSender mailSender;
	
	@RequestMapping(value = "/email")
	public String emailPage() {
		
		return "email";
	}
	
	@RequestMapping(value="/searchPw.do", method=RequestMethod.GET)
    public ModelAndView sendEmailAction (@RequestParam Map<String, Object> paramMap, ModelMap model, ModelAndView mv) throws Exception {
 
        String USERNAME = (String) paramMap.get("username");
        String EMAIL = (String) paramMap.get("email");
        String PASSWORD = "1111111111";
             
        try {
            MimeMessage msg = mailSender.createMimeMessage();
            MimeMessageHelper messageHelper = new MimeMessageHelper(msg, true, "UTF-8");
             
            messageHelper.setSubject(USERNAME+"님 비밀번호 찾기 메일입니다.");
            messageHelper.setText("비밀번호는 "+PASSWORD+" 입니다.");
            messageHelper.setTo(EMAIL);
            msg.setRecipients(MimeMessage.RecipientType.TO , InternetAddress.parse(EMAIL));
            mailSender.send(msg);
             
        }catch(MessagingException e) {
            System.out.println("MessagingException");
            e.printStackTrace();
        }
//        mv.setViewName("redirect:/emailSuccess");
        mv.setViewName("emailSuccess");
        return mv;
    }

}

 

- 정상동작 확인

 

 

 

 

 

4. JSP에서 gmail인증 api 사용법

 

- 라이브러리(jar파일)을 직접 외부에서 다운로드 후, /WEB-INF/lib/ 경로에 추가해줍니다.

 

 

 

- 라이브러리 다운로드

 

activation.jar
0.05MB
mail.jar
0.50MB

 

 

- 실습 진행을 위해 servlet-context.xml 파일에 view(jsp) 파일의 경로 및 설정을 주석처리한다.(ViewResolver)

 

 

 

- view(jsp 파일)의 위치를 /webapp/ 으로 이동시킨다.(만약 파일이 없다면 신규작성)

 

 

 

- email.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>

<body>
    <div>
        <form action="searchPw.jsp" method="get">
            <h2>비밀번호 찾기</h2>
            <p>
                아래 이메일주소를 입력하시면,<br> 입력하신 이메일로 새암호를 보내드립니다<br>
                <br>
            <div>
                <input type="text" name="username" placeholder="이름">
            </div>
            <div>
                <input type="text" name="email" placeholder="이메일주소">
                <p>'@'포함한 이메일주소를 정확히 입력해주세요.</p>
            </div>
 
            <div>
                <button type="submit">비밀번호찾기</button>
            </div>
        </form>
    </div>
</body>


</html>

 

- emailSuccess.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>

<body>
    <h1>이메일이 정상적으로 발송되었습니다.</h1>
</body>

</html>

 

- searchPw.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page import="javax.activation.*"%>
<%@ page import="javax.mail.*"%>
<%@ page import="javax.mail.internet.*"%>
<%!
public class MyAuthentication extends Authenticator { //아이디 패스워드 인증받기 함수
  PasswordAuthentication pa;
  public MyAuthentication(){
    pa=new PasswordAuthentication("발신인 이메일@gmail.com","발신인 이메일의 비밀번호");        
  }
  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
    return pa;
  }
}
%>


<%
 // SMTP 서버 주소
 String smtpHost = "smtp.gmail.com";


 //받는 사람의 정보
 String toName = request.getParameter("username");
 String toEmail = request.getParameter("email");


 //보내는 사람의 정보
 String fromName = "메일 보내는사람 이름";
 String fromEmail = "발신인 이메일@gmail.com";
 
 try {
  Properties props = new Properties();
props.put("mail.smtp.user", fromEmail);
props.put("mail.smtp.host", "smtp.googlemail.com");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.debug", "true");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");

  // 메일 인증
  Authenticator myauth=new MyAuthentication(); 
  Session sess=Session.getInstance(props, myauth);


  InternetAddress addr = new InternetAddress();
  addr.setPersonal(fromName,"UTF-8");
  addr.setAddress(fromEmail);


  Message msg = new MimeMessage(sess);
  msg.setFrom(addr);         
  msg.setSubject(MimeUtility.encodeText("이메일 제목", "utf-8","B"));
  msg.setContent("이메일 보낼 내용", "text/html;charset=utf-8");
  msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));


  Transport.send(msg);


 } catch (Exception e) {
  e.printStackTrace();
  out.println("<script>alert('메일 전송에 실패했습니다.\\n다시 시도해주세요.');</script>");
  return;
 }
 
 out.println("<script>alert('메일이 전송되었습니다.');<script>");

%>

 

- 브라우저에서 실행해봅니다. 이때 주의하실점은 ViewResolver를 주석처리 하였으므로 .jsp까지 포함한 url을 입력하셔야 한다는 점입니다.

 

 

- 발송확인

 

 

 

- 내용확인

 

 

 

완료

반응형
Comments