Java - Spring &&n SpringBoot

Spring Boot - 회원가입 시 인증 메일 발송(feat.네이버 이메일 연결)

TerianP 2022. 8. 8.
728x90

오늘은 학원에서 파이널 프로젝트때 사용했던 사이트 회원 가입 시 인증 메일을 발송하는 부분을 정리해볼까 한다.

당연히 SpringBoot 를 사용하였고, Gradle 을 사용해서 라이브러를 import 하였다.

 

본 포스티에 사용된 모든 코드는 아래 git 에서 확인 가능합니다

https://github.com/SeJonJ/GoodJob

 

GitHub - SeJonJ/GoodJob: 취업정보 제공 GoobJob 사이트

취업정보 제공 GoobJob 사이트. Contribute to SeJonJ/GoodJob development by creating an account on GitHub.

github.com

 

1. Spring 라이브러리 다운받기

Spring 에서 메일 서버와 연결해서 메일을 보내는 작업을 하는데 꼭 필요한 라이브러리가 있다. 바로 spring-boot-starter-mail 라이브러리이다.

이것을 다운받아서 임포트!!

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail

// spring mail
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail
implementation 'org.springframework.boot:spring-boot-starter-mail:2.7.1'

 

2. MailConfig

Spring 에서 메일 서버를 사용하기 위해서는 메일 서버와 연결해야한다. spring 자체적으로 메일을 보내고 받는 것이 아닌 smtp 메일 서버를 사용해서 메일을 보내는 만큼 spring 안에서 어떤 메일 서버와 연결하는지 서버 도메인 주소, 접속 가능한 아이디, 비밀번호가 필수로 있어야한다.

학원에서 다른 사람들과 같이 파이널 프로젝트로 진행했던 만큼 내가 만들어두었던 개인 메일 서버가 아닌 네이버 메일 서버를 사용했다 => 네이버를 사용하기위해 새로 계정을 만들었다

 

1) 네이버 메일서버를 외부에서 연결하기 위해서는 pop3/SMTP 설정을 필수로 해야한다.

설정은 아래 사진처럼 잡아주었다.

네이버 로그인 -> 메일 -> 환경설정
여기서 smtp 서버명, smtp 포트, ssl 보안 연결 여부 등을 꼭!! 확인한다

 

2) 이후 MailConfig class 를 작성한다

이때 해당 클래스를 Spring Bean 으로 꼭 등록해야한다. 즉 Bean 어노테이션이 필수!!

package kr.co.goodjobproject.config;

import java.util.Properties;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

@Configuration
public class MailConfig {

    @Bean
    public JavaMailSender javaMailService() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        javaMailSender.setHost("smtp.naver.com"); // 메인 도메인 서버 주소 => 정확히는 smtp 서버 주소
        javaMailSender.setUsername("네이버 아이디"); // 네이버 아이디
        javaMailSender.setPassword("네이버 비밀번호"); // 네이버 비밀번호

        javaMailSender.setPort(465); // 메일 인증서버 포트

        javaMailSender.setJavaMailProperties(getMailProperties()); // 메일 인증서버 정보 가져오기

        return javaMailSender;
    }
    
    private Properties getMailProperties() {
        Properties properties = new Properties();
        properties.setProperty("mail.transport.protocol", "smtp"); // 프로토콜 설정
        properties.setProperty("mail.smtp.auth", "true"); // smtp 인증
        properties.setProperty("mail.smtp.starttls.enable", "true"); // smtp strattles 사용
        properties.setProperty("mail.debug", "true"); // 디버그 사용
        properties.setProperty("mail.smtp.ssl.trust","smtp.naver.com"); // ssl 인증 서버는 smtp.naver.com
        properties.setProperty("mail.smtp.ssl.enable","true"); // ssl 사용
        return properties;
    }
}

 

3. 메일 내용 작성 및 보내기 클래스 작성 => RegisterMail

해당 클래스는 크게 3가지 메서드로 나뉜다.

1)  createMessage 는 메일의 내용을 작성하는 클래스이다. 여기서 받는 사람의 이메일 주소를 지정 후 메일 내용, 보내는 사람의 메일 주소, 보내는 사람의 이름 등을 지정할 수 있다.

2) createKEy() 메서드는 랜덤한 8자리의 인증 코드를 작성하는 메서드이다. rnd 값에 따라서 switch 문이 실행되고 영어 소문자, 대문자, 숫자가 생성된다.

3) sendSimpleMessage 는 실제로 메일을 발송하는 메서드이다. 매개변수로 들어온 to 를 createMessage 의 매개변수로 넣어서 해당 이메일 주소로 보낼 메일 내용을 담고, emailsender.send 를 사용해서 실제로 메일을 발송한다.

이때 ePw 를 return 하는데 이는 메일로 보낸 인증 코드를 서버에서 저장하고 있다가 사용자가 인증번호를 적었을 때 인증하기 위함이다.

import java.io.UnsupportedEncodingException;
import java.util.Random;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Service
public class RegisterMail implements MailServiceInter {

	@Autowired
	JavaMailSender emailsender; // Bean 등록해둔 MailConfig 를 emailsender 라는 이름으로 autowired

	private String ePw; // 인증번호

	// 메일 내용 작성
	@Override
	public MimeMessage createMessage(String to) throws MessagingException, UnsupportedEncodingException {
//		System.out.println("보내는 대상 : " + to);
//		System.out.println("인증 번호 : " + ePw);
		
		MimeMessage message = emailsender.createMimeMessage();

		message.addRecipients(RecipientType.TO, to);// 보내는 대상
		message.setSubject("GoodJob 회원가입 이메일 인증");// 제목

		String msgg = "";
		msgg += "<div style='margin:100px;'>";
		msgg += "<h1> 안녕하세요</h1>";
		msgg += "<h1> 통합 취업 정보 포탈 GoodJob 입니다</h1>";
		msgg += "<br>";
		msgg += "<p>아래 코드를 회원가입 창으로 돌아가 입력해주세요<p>";
		msgg += "<br>";
		msgg += "<p>항상 당신의 꿈을 응원합니다. 감사합니다!<p>";
		msgg += "<br>";
		msgg += "<div align='center' style='border:1px solid black; font-family:verdana';>";
		msgg += "<h3 style='color:blue;'>회원가입 인증 코드입니다.</h3>";
		msgg += "<div style='font-size:130%'>";
		msgg += "CODE : <strong>";
		msgg += ePw + "</strong><div><br/> "; // 메일에 인증번호 넣기
		msgg += "</div>";
		message.setText(msgg, "utf-8", "html");// 내용, charset 타입, subtype
		// 보내는 사람의 이메일 주소, 보내는 사람 이름
		message.setFrom(new InternetAddress("goodjobproject@naver.com", "GoodJob_Admin"));// 보내는 사람

		return message;
	}

	// 랜덤 인증 코드 전송
	@Override
	public String createKey() {
		StringBuffer key = new StringBuffer();
		Random rnd = new Random();

		for (int i = 0; i < 8; i++) { // 인증코드 8자리
			int index = rnd.nextInt(3); // 0~2 까지 랜덤, rnd 값에 따라서 아래 switch 문이 실행됨

			switch (index) {
			case 0:
				key.append((char) ((int) (rnd.nextInt(26)) + 97));
				// a~z (ex. 1+97=98 => (char)98 = 'b')
				break;
			case 1:
				key.append((char) ((int) (rnd.nextInt(26)) + 65));
				// A~Z
				break;
			case 2:
				key.append((rnd.nextInt(10)));
				// 0~9
				break;
			}
		}

		return key.toString();
	}

	// 메일 발송
	// sendSimpleMessage 의 매개변수로 들어온 to 는 곧 이메일 주소가 되고,
	// MimeMessage 객체 안에 내가 전송할 메일의 내용을 담는다.
	// 그리고 bean 으로 등록해둔 javaMail 객체를 사용해서 이메일 send!!
	@Override
	public String sendSimpleMessage(String to) throws Exception {

		ePw = createKey(); // 랜덤 인증번호 생성

		// TODO Auto-generated method stub
		MimeMessage message = createMessage(to); // 메일 발송
		try {// 예외처리
			emailsender.send(message);
		} catch (MailException es) {
			es.printStackTrace();
			throw new IllegalArgumentException();
		}


		return ePw; // 메일로 보냈던 인증 코드를 서버로 반환
	}
}

 

4. AccountController

accountController 는 계정 전반에 관해 처리하기 위한 컨트롤러이다. view 에서 사용자가 메일 인증 버튼을 누른 순간 ajax 를 통해 이곳의 mailConfirm 메서드가 실행되고, 넘어온 메일로 인증 코드가 발송되며, 메일로 보내졌던 인증 코드는 다시 return 되어서 view 로 돌아간다.

// 이메일 인증
@PostMapping("login/mailConfirm")
@ResponseBody
String mailConfirm(@RequestParam("email") String email) throws Exception {

   String code = registerMail.sendSimpleMessage(email);
   System.out.println("인증코드 : " + code);
   return code;
}

 

 

5. 회원가입 view

회원가입 view 에서는 ajax 를 통해서 서버로부터 return 된 인증코드와 사용자가 입력한 인증코드를 실시간으로 비교해서 틀렸는지 맞았는지 확인해준다.

 

<script>
// 이메일 인증번호
$checkEmail.click(function() {
   $.ajax({
      type : "POST",
      url : "login/mailConfirm",
      data : {
         "email" : $memail.val()
      },
      success : function(data){
         alert("해당 이메일로 인증번호 발송이 완료되었습니다. \n 확인부탁드립니다.")
         console.log("data : "+data);
         chkEmailConfirm(data, $memailconfirm, $memailconfirmTxt);
      }
   })
})

	// 이메일 인증번호 체크 함수
	function chkEmailConfirm(data, $memailconfirm, $memailconfirmTxt){
		$memailconfirm.on("keyup", function(){
			if (data != $memailconfirm.val()) { //
				emconfirmchk = false;
				$memailconfirmTxt.html("<span id='emconfirmchk'>인증번호가 잘못되었습니다</span>")
				$("#emconfirmchk").css({
					"color" : "#FA3E3E",
					"font-weight" : "bold",
					"font-size" : "10px"

				})
				//console.log("중복아이디");
			} else { // 아니면 중복아님
				emconfirmchk = true;
				$memailconfirmTxt.html("<span id='emconfirmchk'>인증번호 확인 완료</span>")

				$("#emconfirmchk").css({
					"color" : "#0D6EFD",
					"font-weight" : "bold",
					"font-size" : "10px"

				})
			}
		})
	}
</script>


<body>
			<!-- <span>이메일 </span> -->
							<div class="form-group last mb-4 email_input">
								<label for="memail" id="mailTxt">이메일을 입력해주세요</label> 
								<input type="text" class="form-control" name="memail" id="memail">
							</div>
							<!-- <span>이메일 인증번호</span> -->
							<button class="btn btn-outline-primary" type="button" id="checkEmail">인증번호</button>


							<div class="form-group last mb-4 check_input">
								<label for="memailconfirm" id="memailconfirmTxt">인증번호를 입력해주세요</label> 
								<input type="text" class="form-control" id="memailconfirm">
							</div>
</body>

코드 확인!!

댓글