Web/스프링

Java: Spring프로젝트에 이메일 인증 기능 추가

벨포트조던 2017. 6. 15.
반응형

http://vip00112.tistory.com/24



Spring MVC기반 RESTfull 사이트를 개발中..

이메일 관련한 기능을 추가로 작업해주길 요청 받았다.

Spring 프레임워크와 Gmail SMTP를 이용하면 어렵지 않게 해당 기능을 구현 가능 하다.


- 추가 요청 기능

1. 회원가입시 이메일 인증

1) 회원정보 입력 전 이메일로 인증 코드 발송

2) 시간내 일치하는 인증 코드 입력 후 다음 프로세스 진행(회원정보 입력)

2. 이메일 기반 아이디/비밀번호 찾기

1) 아이디 찾기: 입력한 이메일로 가입된 정보가 있을시 해당 이메일로 아이디 전송

2) 비밀번호 찾기: 입력한 이메일/아이디로 일치하는 회원 정보가 있을시 해당 이메일로 임시 비밀번호 전송


- 필요한 라이브러리

1. spring-context-support-4.2.5.RELEASE.jar (프로젝트에 사용된 spring 버전과 일치해야 함)

2. javax.mail-1.5.6.jar

3. maven일 경우

1
2
3
4
5
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4</version>
</dependency>


- 프로세스

1. view페이지 에서 이메일 입력 후 전송 버튼 클릭

- Controller에 mapping된 url로 form submit

2. Controller에서 인증 코드 생성 및 session의 Attribute에 저장

3. Service에서 실제 메일 전송


- xml 설정 및 소스 코드

1. MailService Interface 및 이를 구현한 MailServiceImpl 클래스 생성

1
2
3
4
5
6
7
8
9
10
11
12
// Interface
public interface MailService {
 
    /** 메일 전송
     *  @param subject 제목
     *  @param text 내용
     *  @param from 보내는 메일 주소
     *  @param to 받는 메일 주소
     *  @param filePath 첨부 파일 경로: 첨부파일 없을시 null **/
    public boolean send(String subject, String text, String from, String to, String filePath);
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// MailService Interface 구현 클래스
@Service
public class MailServiceImpl implements MailService {
    // org.springframework.mail.javamail.JavaMailSender
    private JavaMailSender javaMailSender;
 
    public void setJavaMailSender(JavaMailSender javaMailSender) {
        this.javaMailSender = javaMailSender;
    }
 
    @Override
    public boolean send(String subject, String text, String from, String to, String filePath) {
        // javax.mail.internet.MimeMessage
        MimeMessage message = javaMailSender.createMimeMessage();
 
        try {
            // org.springframework.mail.javamail.MimeMessageHelper
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
            helper.setSubject(subject);
            helper.setText(text, true);
            helper.setFrom(from);
            helper.setTo(to);
 
            // 첨부 파일 처리
            if (filePath != null) {
                File file = new File(filePath);
                if (file.exists()) {
                    helper.addAttachment(file.getName(), new File(filePath));
                }
            }
 
            javaMailSender.send(message);
            return true;
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        return false;
    }
}


2. applicationContext.xml에 bean 등록

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- 이메일 관련 -->
<bean id="javaMailSender" 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.ssl.trust">smtp.gmail.com</prop>
            <prop key="mail.smtp.starttls.enable">true</prop>
            <prop key="mail.smtp.auth">true</prop>
        </props>
    </property>
</bean>
<bean id="mailService" class="service.other.MailServiceImpl">
    <property name="javaMailSender" ref="javaMailSender" />
</bean>


3. view페이지의 요청을 받아서 처리할 MailController 클래스 생성

- userService관련 내용은 여기서 따로 다루지 않는다. (개별 구현 할것)

- captcha는 이메일과 상관없이 따로 구현한 기능이다. (생략 가능)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
@Controller
public class MailController {
    private UserService userService;
    private MailService mailService;
 
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
 
    public void setMailService(MailService mailService) {
        this.mailService = mailService;
    }
 
    // 회원가입 이메일 인증
    @RequestMapping(value = "/sendMail/auth", method = RequestMethod.POST, produces = "application/json")
    @ResponseBody
    public boolean sendMailAuth(HttpSession session, @RequestParam String email) {
        int ran = new Random().nextInt(100000) + 10000; // 10000 ~ 99999
        String joinCode = String.valueOf(ran);
        session.setAttribute("joinCode", joinCode);
 
        String subject = "회원가입 인증 코드 발급 안내 입니다.";
        StringBuilder sb = new StringBuilder();
        sb.append("귀하의 인증 코드는 " + joinCode + " 입니다.");
        return mailService.send(subject, sb.toString(), "아이디@gmail.com", email, null);
    }
 
    // 아이디 찾기
    @RequestMapping(value = "/sendMail/id", method = RequestMethod.POST)
    public String sendMailId(HttpSession session, @RequestParam String email, @RequestParam String captcha, RedirectAttributes ra) {
        String captchaValue = (String) session.getAttribute("captcha");
        if (captchaValue == null || !captchaValue.equals(captcha)) {
            ra.addFlashAttribute("resultMsg", "자동 방지 코드가 일치하지 않습니다.");
            return "redirect:/find/id";
        }
 
        User user = userService.findAccount(email);
        if (user != null) {
            String subject = "아이디 찾기 안내 입니다.";
            StringBuilder sb = new StringBuilder();
            sb.append("귀하의 아이디는 " + user.getId() + " 입니다.");
            mailService.send(subject, sb.toString(), "아이디@gmail.com", email, null);
            ra.addFlashAttribute("resultMsg", "귀하의 이메일 주소로 해당 이메일로 가입된 아이디를 발송 하였습니다.");
        } else {
            ra.addFlashAttribute("resultMsg", "귀하의 이메일로 가입된 아이디가 존재하지 않습니다.");
        }
        return "redirect:/find/id";
    }
 
    // 비밀번호 찾기
    @RequestMapping(value = "/sendMail/password", method = RequestMethod.POST)
    public String sendMailPassword(HttpSession session, @RequestParam String id, @RequestParam String email, @RequestParam String captcha, RedirectAttributes ra) {
        String captchaValue = (String) session.getAttribute("captcha");
        if (captchaValue == null || !captchaValue.equals(captcha)) {
            ra.addFlashAttribute("resultMsg", "자동 방지 코드가 일치하지 않습니다.");
            return "redirect:/find/password";
        }
 
        User user = userService.findAccount(email);
        if (user != null) {
            if (!user.getId().equals(id)) {
                ra.addFlashAttribute("resultMsg", "입력하신 이메일의 회원정보와 가입된 아이디가 일치하지 않습니다.");
                return "redirect:/find/password";
            }
            int ran = new Random().nextInt(100000) + 10000; // 10000 ~ 99999
            String password = String.valueOf(ran);
            userService.updateInfo(user.getNo(), "password", password); // 해당 유저의 DB정보 변경
 
            String subject = "임시 비밀번호 발급 안내 입니다.";
            StringBuilder sb = new StringBuilder();
            sb.append("귀하의 임시 비밀번호는 " + password + " 입니다.");
            mailService.send(subject, sb.toString(), "아이디@gmail.com", email, null);
            ra.addFlashAttribute("resultMsg", "귀하의 이메일 주소로 새로운 임시 비밀번호를 발송 하였습니다.");
        } else {
            ra.addFlashAttribute("resultMsg", "귀하의 이메일로 가입된 아이디가 존재하지 않습니다.");
        }
        return "redirect:/find/password";
    }


4. DispatcherServle xml에 Controller bean 등록 (xml 이름은 프로젝트마다 상이할 수 있습니다.)

- web.xml에서 지정한 DispatcherServlet xml파일

- 해당 프로젝트에서는 owm-servlet.xml 이다.

1
2
3
4
<bean class="controller.MailController">
    <property name="userService" ref="userService" />
    <property name="mailService" ref="mailService" />
</bean>


5. view 페이지 작성

- 대표로 아이디 찾기 form만 남긴다.

- captcha는 이메일과 상관없이 따로 구현한 기능이다. (생략 가능)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<form action="/sendMail/id" id="findForm" method="post">
    <fieldset>
        <legend class="screen_out">아이디 찾기 폼</legend>
 
        <div class="box email">
            <label for="email">이메일</label>
            <input type="text" id="email" name="email" autofocus autocomplete="off" required />
        </div>
        <!-- // .box.email -->
 
        <div class="box captcha">
            <div class="loading"></div>
            <!-- // .loading -->
 
            <label for="captcha">자동 방지 코드</label>
            <input type="text" id="captcha" name="captcha" autocomplete="off" required />
            <img src="/captcha" alt="캡차 이미지" title="클릭시 새로고침" />
        </div>
        <!-- // .box.captcha -->
 
        <div class="box btn">
            <button type="submit" class="btn join">
                <i class="fa fa-envelope"></i>
                이메일 전송
            </button>
        </div>
        <!-- // .box.btn -->
    </fieldset>
</form>


반응형

댓글