공부한것들을 정리하는 블로그 입니다.
15. gmail로 email 인증번호 보내기(비밀번호 찾기 기능/ 회원가입시 이메일 인증) 본문
15. gmail로 email 인증번호 보내기(비밀번호 찾기 기능/ 회원가입시 이메일 인증)
호 두 2017. 6. 15. 11:12
** (2019.12.13)
- 해당글이 2017년에 작성되었기 때문에 기능점검 및 가독성 문제로 다시 포스팅했습니다.
- 이 글을 참고하셔도 좋지만 좀 더 깔끔하게 기능구현만을 원하시는 분들은 아래 링크의 글을 참고해주세요.
(2019.12.13 버전) : https://drsggg.tistory.com/403
내용요약 :
1. 사전작업 - 구글 보안정책 : 구글 보안정책 관련하여 본인의 이메일 계정에 대해 몇가지 조치가 필요합니다.
- POP/IMAP 활성화
- 2단계 인증 활성화 (이건 안해도 됬던걸로 기억합니다. 그냥 보안절차상 넣었습니다.)
- 계정에 대한 "보안수준이 낮은 앱의 액세스를 허용" 하고, 실습종료 후 원복 (다시 비허용)
2. 스프링부트에서 gmail인증 api 사용법 (내장톰캣 사용 - 톰캣 다운로드 필요x)
- 설정파일(properties 파일)을 통한 사용
3. SpringMVC에서 gmail인증 api 사용법
- 설정파일(xml 파일)을 통한 사용
4. JSP에서 gmail인증 api 사용법
=========================================================================
pom.xml로 받아준 뒤
root-context에서 dependency 추가해줌
pom.xml
<!-- 이메일 인증 기능 -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mail</artifactId>
<version>4.3.8.RELEASE</version>
</dependency>
root-context.xml
<!-- email 인증 : gmail -->
<bean id="mailSender" class ="org.springframework.mail.javamail.JavaMailSenderImpl" >
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="defaultEncoding" value="utf-8"/>
<property name="username" value="구글이메일@gmail.com" />
<property name="password" value="구글비밀번호" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.auth">true</prop>
</props>
</property>
</bean>
<bean id="email" class="org.poom.sap.member.model.vo.Email">
</bean>
<bean id="emailSender" class="org.poom.sap.common.util.EmailSender">
</bean>
에러 발생함. javamailsender가 import되지 않아서
javamailsendhelper를 사용했더니 해결
그래도 에러가 떠서(이번엔 smpt 때문이라 판단)
그냥 maven 저장소에서 smpt, javamailsender, sendhelper 등 관련 라이브러리를 다운받은 후
라이브러리에서 직접 추가해주었더니 해결
(파일첨부 함)
import 되지 않는 문제는 maven repository를 직접 다운로드 받아서 webapp/WEB-INF/lib 폴더에 넣은 후
프로젝트 우클릭 - properties - java build path - libraries - add jars.. 를 이용하여
라이브러리에 추가시켜 주는 방법으로 해결
maven repository 다운로드 받는 곳
https://mvnrepository.com/search?q=activation
다운받아 사용한 maven repository들
view : searchPw.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 charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>비밀번호찾기1</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/sap/resources/css/searchPw.css">
</head>
<body>
<div class="contact-clean">
<form action="searchPw.do" method="get">
<h2 class="text-center">비밀번호 찾기</h2>
<p class="text-center">
아래 이메일주소를 입력하시면,<br> 입력하신 이메일로 새암호를 보내드립니다<br>
<br>
<div class="form-group has-success has-feedback">
<input type="text" name="username" placeholder="username"
class="form-control" /><i aria-hidden="true"
class="form-control-feedback glyphicon glyphicon-ok"></i>
</div>
<div class="form-group has-error has-feedback">
<input type="email" name="email" placeholder="email"
class="form-control" /><i aria-hidden="true"
class="form-control-feedback glyphicon glyphicon-remove"></i>
<p class="help-block">'@'포함한 이메일주소를 정확히 입력해주세요.</p>
</div>
<div class="form-group">
<button allign="center" class="btn btn-primary" type="submit">비밀번호찾기</button>
</div>
</form>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
root-context.xml에서 명시해준 emailSender
package org.poom.sap.common.util;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.poom.sap.member.model.vo.Email;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
public class EmailSender {
@Autowired
private JavaMailSender mailSender;
public void SendEmail(Email email) throws Exception {
System.out.println(email);
MimeMessage msg = mailSender.createMimeMessage();
try {
msg.setSubject(email.getSubject());
msg.setText(email.getContent());
msg.setRecipients(MimeMessage.RecipientType.TO , InternetAddress.parse(email.getReceiver()));
mailSender.send(msg);
}catch(MessagingException e) {
System.out.println("MessagingException");
e.printStackTrace();
}
}
}
root-context.xml에서 명시해준 email
package org.poom.sap.member.model.vo;
public class Email {
private String subject;
private String content;
private String receiver;
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "Email [subject=" + subject + ", content=" + content + ", receiver=" + receiver + "]";
}
}
controller : MemberController
package org.poom.sap.member.controller;
import java.util.Map;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.log4j.Logger;
import org.poom.sap.common.util.EmailSender;
import org.poom.sap.file.model.service.FileService;
import org.poom.sap.member.model.service.MemberService;
import org.poom.sap.member.model.vo.Email;
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
@RequestMapping("member")
public class MemberController {
Logger log = Logger.getLogger(this.getClass());
@Autowired
private MemberService memberService;
@Autowired
private EmailSender emailSender;
@Autowired
private Email email;
@Autowired
private FileService fileService;
@RequestMapping(value="/searchPwForm.do", method=RequestMethod.GET)
public String searchIdForm(){
return "member/searchPw";
}
@Autowired
private JavaMailSender mailSender;
@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 = memberService.getPw(paramMap);
if(PASSWORD!=null) {
email.setContent("비밀번호는 "+PASSWORD+" 입니다."); // 이메일로 보낼 메시지
email.setReceiver(EMAIL); // 받는이의 이메일 주소
email.setSubject(USERNAME+"님 비밀번호 찾기 메일입니다."); // 이메일로 보낼 제목
try {
MimeMessage msg = mailSender.createMimeMessage();
MimeMessageHelper messageHelper
= new MimeMessageHelper(msg, true, "UTF-8");
messageHelper.setSubject(email.getSubject());
messageHelper.setText(email.getContent());
messageHelper.setTo(email.getReceiver());
messageHelper.setFrom("구글이메일@gmail.com"); // 보내는 이의 주소(root-context.xml 에서 선언했지만 적어줬음)
msg.setRecipients(MimeMessage.RecipientType.TO , InternetAddress.parse(email.getReceiver()));
mailSender.send(msg);
}catch(MessagingException e) {
System.out.println("MessagingException");
e.printStackTrace();
}
mv.setViewName("redirect:/noriter/noriterList.do");
return mv;
}else {
mv.setViewName("redirect:/noriter/noriterList.do");
return mv;
}
}
}
근데 위의 controller 코드에서는 EmailSender를 실수로 import하지 않았었음.
아래처럼 EmailSender를 import하면 될 것이라 생각함(이 코드는 직접 사용해보진 않았음)
package org.poom.sap.member.controller;
import org.poom.sap.common.util.EmailSender;
@SuppressWarnings("unused")
@Controller
@RequestMapping("member")
/*@SessionAttributes("loginUser")*/
public class MemberController {
Logger log = Logger.getLogger(this.getClass());
@Autowired
private MemberService memberService;
@Autowired
private EmailSender emailSender;
@Autowired
private Email email;
}
MemberService
package org.poom.sap.member.model.service;
import java.util.Map;
public interface MemberService {
String getPw(Map<String, Object> paramMap);
}
MemberServiceImpl
package org.poom.sap.member.model.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
import org.apache.log4j.Logger;
import org.poom.sap.member.model.dao.MemberDao;
@Service("memberService")
public class MemberServiceImpl implements MemberService{
Logger log = Logger.getLogger(this.getClass());
@Autowired
MemberDao memberDao;
@Override
public String getPw(Map<String, Object> paramMap) {
return memberDao.getPw(paramMap);
}
}
MemberDao
package org.poom.sap.member.model.dao;
import java.util.Map;
import org.apache.log4j.Logger;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository("memberDao")
public class MemberDao {
Logger log = Logger.getLogger(this.getClass());
@Autowired
private SqlSessionTemplate sqlSession;
public MemberDao(){}
public String getPw(Map<String, Object> paramMap) {
return (String) sqlSession.selectOne("emailSendPW", paramMap);
}
}
member-mapper는 나중에 올려드리도록 하겠습니다.(버전관리가 서툴러서.. 코드를 날려버린 탓에 지금 해당부분은 남아있지가 않네요ㅜㅜ 나중에 시간이 되면 추가해 보도록 하겠습니다)
그래도 controller를 조금 변경하는 선에서 기능의 확인이 가능합니다
String PASSWORD = memberService.getPw(paramMap); 를
String PASSWORD = "바뀐 비밀번호"; 로 놓으면 됩니다
사실은 난수를 발생시켜서 비밀번호를 변경시킨 후 해당 비밀번호를 이메일로 보내줘야하지만 기능을 확인만 하는 것은 이정도로도 가능합니다.
이렇게 코딩을 완료 한 후 실행했더니
접근 권한 관련 에러 뜨길래
avast 실시간 감시 꺼주고 gmail POP/IMAP 활성화 하었더니 해결
( 참고 : https://support.google.com/mail/answer/7104828?hl=ko )
명령 구문(규칙)에 오류 있다고 에러 뜨길래
controller from을 추가해주었더니 해결
(원래는 to, context, title만 있었음, from은 context에서 설정해주긴 했었는데 그것과는 별개로 또 추가해주었음)
(이 부분은 이에 controller 부분에서 밝혔듯이 import가 누락되어서 autowired가 안된 까닭이라 생각함)
---------------------------------------------------------------------------------
진행했던 순서 (오류발생과 해결)
pom.xml로 받아준 뒤
context에서 dependency 추가해줌
에러 발생함. javamailsender가 import되지 않아서
javamailsendhelper를 사용했더니 해결
그래도 에러가 떠서(이번엔 smpt 때문이라 판단)
그냥 maven 저장소에서 smpt, javamailsender, sendhelper 등 관련 라이브러리를 다운받은 후
라이브러리에서 직접 추가해주었더니 해결
(파일첨부 함)
실행했더니 접근 권한 관련 에러 뜨길래
avast 실시간 감시 꺼주고 gmail POP/IMAP 활성화 하었더니 해결
( 참고 : https://support.google.com/mail/answer/7104828?hl=ko )
명령 구문(규칙)에 오류 있다고 에러 뜨길래
controller from을 추가해주었더니 해결
(원래는 to, context, title만 있었음, from은 context에서 설정해주긴 했었는데 그것과는 별개로 또 추가해주었음)
(이 부분은 이에 controller 부분에서 밝혔듯이 import가 누락되어서 autowired가 안된 까닭이라 생각함)
참고 :
---------------------------------------------------------------------------------
추가로 공부해볼만한 것 :
- validation 체크 추가/ 난수를 발생시켜서 비밀번호를 변경 후 이메일로 값을 보내기
http://vip00112.tistory.com/24
---------------------------------------------------------------------------------
'(2017) 사이드 프로젝트 > fnl-project(게시판)' 카테고리의 다른 글
14. search 검색 기능 (0) | 2017.06.09 |
---|---|
0. 스프링(Spring) 개발 -개발환경 구성하기 [Eclipse+Maven+SVN] (0) | 2017.06.09 |
- Spring 따라하기_샘플 (0) | 2017.06.09 |
- spring 셋팅(pom, log4j, interceptor, mvc작성, mapper작성 등)과 db 셋팅(샘플데이터) (0) | 2017.06.09 |
13. 최신 공지사항 글이 메인 상단에 출력 : ajax (0) | 2017.06.05 |
12. 카테고리 항목 추가 : 카테고리별로 불러오기(DB조인) (0) | 2017.06.04 |
11. interceptor를 이용한 로그인 session처리 (0) | 2017.05.26 |
10. 페이징 처리하기 (2) | 2017.05.26 |