Spring Boot SMTP 서버를 통한 이메일 인증기능 구현

이동명·2023년 5월 26일
0
post-thumbnail

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

Spring에서 메일 서버와 연결하여 이메일을 발송할 때 spring-boot-starter-mail 라이브러리가 필요하다

spring-boot-starter-mail 2.7.2

위에서 Maven탭의 코드를 복사하여 pom.xml에 추가해준다

2. Mail서버 연결

Spring에서 메일 서버를 사용하기 위해 사용할 메일 서버와 연결해야한다

Spring에서 자체적으로 메일을 주고 받는방식이 아니라,

smtp 메일 서버를 이용하여 메일을 보내는 방식이기 때문에

메일을 보낼때 사용할 메일 서버의 도메인주소, 접속할 아이디, 비밀번호에 대한 정보가 필요하다

a. 네이버 메일서버 연결을 위한 설정

네이버 메일서버를 외부에서 연결하기 위해서는 POP3/SMTP 설정을 필수로 진행해야한다! 아래와 같이 설정하면 된다

a-1. 네이버 메일 하단 환경설정

a-2. POP3/SMTP 설정

smtp 서버명, smtp 포트, ssl 보안연결 여부등을 확인한다

b. MailConfig class 생성

📁 config/MailConfig.java

@Bean 어노테이션을 포함하여 작성해준다

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 NaverMailService(){
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        javaMailSender.setHost("smtp.naver.com");  // SMTP 서버명
        javaMailSender.setUsername("mah95"); // 네이버 아이디
        javaMailSender.setPassword("y7y7y7y7y7"); // 네이버 비밀번호

        javaMailSender.setPort(465); // SMTP 포트

        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 서버명)
        properties.setProperty("mail.smtp.ssl.enable", "true"); // ssl 사용

        return properties;
    }
}

3. 메일내용 작성 및 보내기

메일 내용을 작성하고 보낼때 3가지 메서드를 생성한다

createMessage()⇒ 메일의 내용을 작성하는 클래스이며, 메일 받는사람의 이메일 주소, 보낼 메일의 내용, 보내는 사람의 메일주소, 보내는 사람의 이름등을 지정할 수 있다createKey()⇒ 이메일로 발송한 랜덤한 인증코드를 생성하는 메서드이다sendSimpleMessage()⇒ 실제로 이메일을 발송하는 메서드이다.매개변수로 들어온 to를 createMessage의 매개변수로 넣어 해당 이메일 주소로 보낼 메일 내용을 담고, emailsender.send를 사용하여 실제로 이메일을 발송한다💡 이때 ePw를 return하는데 이는 메일로 보낸 인증코드를 서버에서 저장하고 있다가 사용자가 인증번호를 적었을때 일치여부를 판단할수 있어야 하기 때문이다!

a. MailServiceInter.java 생성

인터페이스를 생성한다

📁 service/MailServiceInter.java

import java.io.UnsupportedEncodingException;

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

import org.springframework.stereotype.Service;

@Service
public interface MailServiceInter {

    // 메일 내용 작성
    MimeMessage creatMessage(String to) throws MessagingException, UnsupportedEncodingException;

    // 랜덤 인증코드 생성
    String createKey();

    // 메일 발송
    String sendSimpleMessage(String to) throws Exception;

}

b. RegisterMail.java

생성한 인터페이스를 상속받아 오버라이드 메서드 구현

📁 service/RegisterMail.java

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.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Service
public class RegisterMail implements MailServiceInter {

    @Autowired
    JavaMailSender emailSender; // MailConfig에서 등록해둔 Bean을 autowired하여 사용하기

    private String ePw; // 사용자가 메일로 받을 인증번호

    // 메일 내용 작성
    @Override
    public MimeMessage creatMessage(String to) throws MessagingException, UnsupportedEncodingException {
        System.out.println("메일받을 사용자" + to);
        System.out.println("인증번호" + ePw);

        MimeMessage message = emailSender.createMimeMessage();

        message.addRecipients(RecipientType.TO, to); // 메일 받을 사용자
        message.setSubject("[Fligent] 비밀번호 변경을 위한 이메일 인증코드 입니다"); // 이메일 제목

        String msgg = "";
        // msgg += "<img src=../resources/static/image/emailheader.jpg />"; // header image
        msgg += "<h1>안녕하세요</h1>";
        msgg += "<h1>원하는 IT 인재 채용 플랫폼 Cozlin 입니다</h1>";
        msgg += "<br>";
        msgg += "<p>아래 인증코드를 암호변경 페이지에 입력해주세요</p>";
        msgg += "<br>";
        msgg += "<br>";
        msgg += "<div align='center' style='border:1px solid black'>";
        msgg += "<h3 style='color:blue'>회원가입 인증코드 입니다</h3>";
        msgg += "<div style='font-size:130%'>";
        msgg += "<strong>" + ePw + "</strong></div><br/>" ; // 메일에 인증번호 ePw 넣기
        msgg += "</div>";
        // msgg += "<img src=../resources/static/image/emailfooter.jpg />"; // footer image

        message.setText(msgg, "utf-8", "html"); // 메일 내용, charset타입, subtype
        // 보내는 사람의 이메일 주소, 보내는 사람 이름
        message.setFrom(new InternetAddress("mah95@naver.com", "Fligent_Admin"));
        System.out.println("********creatMessage 함수에서 생성된 msgg 메시지********" + msgg);

        System.out.println("********creatMessage 함수에서 생성된 리턴 메시지********" + message);

        return message;
    }

    // 랜덤 인증코드 생성
    @Override
    public String createKey() {
            int leftLimit = 48; // numeral '0'
            int rightLimit = 122; // letter 'z'
            int targetStringLength = 10;
            Random random = new Random();
            String key = random.ints(leftLimit, rightLimit + 1)
                                           .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
                                           .limit(targetStringLength)
                                           .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
                                           .toString();
            System.out.println("생성된 랜덤 인증코드"+ key);
            return key;
    }

    // 메일 발송
    // sendSimpleMessage 의 매개변수 to는 이메일 주소가 되고,
    // MimeMessage 객체 안에 내가 전송할 메일의 내용을 담는다
    // bean으로 등록해둔 javaMail 객체를 사용하여 이메일을 발송한다
    @Override
    public String sendSimpleMessage(String to) throws Exception {

        ePw = createKey(); // 랜덤 인증코드 생성
        System.out.println("********생성된 랜덤 인증코드******** => " + ePw);

        MimeMessage message = creatMessage(to); // "to" 로 메일 발송

        System.out.println("********생성된 메시지******** => " + message);

        try { // 예외처리
            emailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalArgumentException();
        }

        return ePw; // 메일로 사용자에게 보낸 인증코드를 서버로 반환! 인증코드 일치여부를 확인하기 위함
    }

}

4. RestController 생성

프론트에서 사용자가 메일 인증버튼을 누른 시점에 실행될 메서드를 RestController에 생성해준다

이 메서드가 실행되는 순간 to의 메일로 인증코드가 발송되며,

메일로 보내졌던 인증코드는 프론트로 return된다

📁 restcontroller/MailServiceRestController.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.service.RegisterMail;

@RestController
@RequestMapping(value = "/api/mail")
public class MailServiceRestController {

    @Autowired
    RegisterMail registerMail;

    //127.0.0.1:8080/ROOT/api/mail/confirm.json?email
    @PostMapping(value = "/confirm.json")
    public String mailConfirm(@RequestParam(name = "email") String email) throws Exception{
        String code = registerMail.sendSimpleMessage(email);
        System.out.println("사용자에게 발송한 인증코드 ==> " + code);

        return code;
    }

}

결과 화면

profile
Web Developer

0개의 댓글