공부한것들을 정리하는 블로그 입니다.
gmail로 email 인증번호 보내기(비밀번호 찾기 기능/ 회원가입시 이메일 인증/smtp) 본문
** 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/ 경로에 추가해줍니다.
- 라이브러리 다운로드
- 실습 진행을 위해 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을 입력하셔야 한다는 점입니다.
- 발송확인
- 내용확인
완료
'JAVA > 공부' 카테고리의 다른 글
JVM에 대하여 정리 (0) | 2022.04.30 |
---|---|
좋은 객체 지향 설계의 5가지 원칙(SOLID) (0) | 2022.04.24 |
접근제한자(Access Modifier) : public, protected, default, private (0) | 2022.04.23 |
싱글톤(Singleton) 디자인패턴 (0) | 2022.04.23 |
추상클래스와 인터페이스 (0) | 2018.11.10 |
JAVA의 배열 길이와 문자열 길이 (0) | 2017.07.30 |
접근제어자 public, protected, private (0) | 2017.07.30 |
자바면접 질문유형 (0) | 2017.07.30 |