티스토리 뷰

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일 경우

<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 클래스 생성

// 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);

}
// 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 등록

<!-- 이메일 관련 -->
<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는 이메일과 상관없이 따로 구현한 기능이다. (생략 가능)

@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 이다.

 

<bean class="controller.MailController">
	<property name="userService" ref="userService" />
	<property name="mailService" ref="mailService" />
</bean>

 

5. view 페이지 작성

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

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

<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>

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday