새소식

반응형
Java/Spring Boot

이메일 인증 회원가입 기능 만들기

  • -
728x90
반응형

환경구성 : Spring Boot, Thymeleaf, Maven

 

일반 게시판 회원가입 기능 구현 과정에서 인증에 필요한 이메일 인증 기능을 해보려고 한다.

 

1. Spring Boot mail dependency 추가

Spring Boot 에서 사용할 mail 라이브러리를 pom.xml 에 추가해준다.

pom.xml 에 <dependencies></dependencies> 태그 사이에 아래 내용을 추가한다.

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

 

위 내용 추가 후 라이브러리 추가를 위해 Maven Update 실행한다.

해당 프로젝트 마우스 오른쪽 클릭 > Maven > Update Project... 클릭 > OK 클릭

 

2. 메일 발송을 위한 GMAIL 가입 및 설정

메일발송을 위한 메일서버가 필요하다. spring 자체적으로 메일서버가 존재하지 않아 

메일 발송은 가능하나 메일을 보내기 위한 SMTP 메일서버가 필요하다.

 

보통 네이버, 구글 등 여러 메일서버를 사용할 수 있으며, 본인은 구글의 gmail 을 사용할 예정이다.

일단 gmail 을 회원가입을 해주자. 아래 내용은 회원가입이 완료된 상태를 기반으로 작성한 내용이다.

(알아서 회원가입 해주세요...)

 

회원가입 후 gmail 을 접속한다. 접속한 후 smtp 설정을 위해 아래 이미지와 같이 클릭한다.

 

2-1. Gmail 상단의 설정(톱니바퀴) 버튼을 클릭한다.

 

2-2. 빠른설정에서 모든 설정보기를 클릭한다.

 

2-3. 설정에서 전달 및 POP/IMAP 설정을 클릭한다.

 

2-4. IMAP 사용 클릭 후 변경사항 저장 버튼을 클릭한다.

2-5. 오른쪽 끝 구글 계정을 클릭하여 "Google 계정 관리"를 클릭한다.

 

2-6. 왼쪽 메뉴에 보안을 클릭한다.

2-7. 보안 탭에서 Google에 로그인 메뉴에서 2단계 인증을 설정해주시고 "앱 비밀번호" 메뉴를 선택한다.

 

2-8. 메일, Windows 컴퓨터 를 선택한 후 생성한다.

2-9. 아래와 같이 패스워드가 생성된다.

해당 패스워드는 기억해둬야 한다. EmailConfig 파일에서 메일을 보내기 위한 계정 비밀번호이다.

 

3. 메일 발송을 위한 Config 설정

3-1. MailConfig 클래스 파일 설정

본인은 패키지 경로에 mail package > config package > EmailConfig 클래스파일을 생성했다.

@Configuration
public class EmailConfig {

    @Value("${mail.smtp.host}")
    private String host;

    @Value("${mail.smtp.auth}")
    private boolean auth;

    @Value("${mail.smtp.transport.protocol}")
    private String protocol;

    @Value("${mail.smtp.starttls.enable}")
    private boolean starttls_enable;

    @Value("${mail.smtp.ssl.enable}")
    private boolean ssl_enable;

    @Value("${mail.smtp.port}")
    private int port;

    @Value("${admin.mail.id}")
    private String id;

    @Value("${admin.mail.pw}")
    private String pw;

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

        sender.setHost(host);
        sender.setPort(port);
        sender.setUsername(id);
        sender.setPassword(pw);
        sender.setDefaultEncoding("UTF-8");
        sender.setJavaMailProperties(getMailProperties());
        return sender;
    }

    public Properties getMailProperties() {
        Properties pt = new Properties();
        pt.put("mail.smtp.auth", auth);
        pt.put("mail.smtp.starttls.enable", starttls_enable);
        pt.put("mail.transport.protocol", protocol);
        return pt;
    }
}

 

@Configuration, @Bean

@Configuration 어노테이션을 통해 Spring Bean 객체를 관리하는 Spring Container 에게 Bean 등록 클래스 파일이라는걸

알려준다. 그리고 @Bean 태그를 통해 Spring Bean 으로 등록한다.

 

JavaMailSender

실제로 메일을 발송할 Java Mail Sender 인터페이스이다.

JavaMailSender 는 MailSender 를 상속받아 아래 이미지와 같이 인터페이스로 작성되어 있다.

이러한 JavaMailSender 인터페이스를 Spring 에서 구현해놓은 클래스파일이 있다.

JavaMailSenderImpl 이다.

JavaMailSender 를 구현한 JavaMailSenderImpl 에서 send() 함수 및 doSend() 함수를 통해 메일을 발송한다.

 

@Value("${mail.smtp.host}")

@Value 어노테이션은 특정 properties 파일에서 공통적인 값을 사용하기 위해 불러오는 어노테이션이다.

 

3-2. properties 파일 설정

src/main/resources(classpath) 경로에 *.properties 파일을 생성한다.

* 에는 아무 파일명이나 설정해주면 된다. 본인은 만들고 있는 웹사이트의 이름으로 했다.

src/main/resources에 local이 붙은 이유는 maven 설정에 profiles를 따로 설정했기 때문에 붙었다.

별로 신경 안써도됩니다.

admin.mail.pw 은 아까 2번에서 설정한 구글계정 앱 비밀번호를 적어준다.

 

그리고 properties 파일을 사용하기 위해 application.yml 에 설정해준다.

spring: config: import: *.properties (*은 생성한 파일명을 적는다. 본인은 baram.properties)

 

3-2. Mail 발송 Service 파일 설정

Mail 발송을 위해 필요한 인터페이스와 클래스 파일을 설정한다.

 

특정 기능에 대한 틀만 구성하는 EmailService 인터페이스를 생성한다.

EmailService.java
public interface EmailService {
    //메일 발송 설정을 위한 메서드
    MimeMessage createMimeMessage(String to) throws Exception;
    //메일 본문에 포함될 인증번호를 설정할 메서드
    String createAuthKey() throws Exception;
    //메일 발송을 위한 메서드
    String sendMessage(String to) throws Exception;
}

 

EmailService 인터페이스를 구현하는 MailSenderService 클래스를 생성한다.

@Service
public class MailSenderService implements EmailService {

    @Value("${admin.from.mail}")
    String fromMail;

    private String authPw;

    private JavaMailSender sender;

    public MailSenderService(JavaMailSender sender) {
        this.sender = sender;
    }

    @Override
    public MimeMessage createMimeMessage(String to) throws Exception {
        MimeMessage message = sender.createMimeMessage();

        message.addRecipients(RecipientType.TO, to);
        message.setSubject("바람톡 이메일 인증 서비스");
        authPw = createAuthKey();
        String msg = "";
        msg+= "<div style='margin:20px;'>";
        msg+= "<h1> 안녕하세요 임준호입니다. </h1>";
        msg+= "<br>";
        msg+= "<p>아래 코드를 복사해 입력해주세요<p>";
        msg+= "<br>";
        msg+= "<p>감사합니다.<p>";
        msg+= "<br>";
        msg+= "<div align='center' style='border:1px solid black; font-family:verdana';>";
        msg+= "<h3 style='color:blue;'>회원가입 인증 코드입니다.</h3>";
        msg+= "<div style='font-size:130%'>";
        msg+= "CODE : <strong>";
        msg+= authPw+"</strong><div><br/> ";
        msg+= "</div>";
        
        message.setText(msg, "utf-8", "html");
        message.setFrom(new InternetAddress("fromMail", "baramtalkadm"));
        return message;
}

    @Override
    public String createAuthKey() {
        StringBuffer key = new StringBuffer();
        Random rnd = new Random();
 
        for (int i = 0; i < 8; i++) { // 인증코드 8자리
            int index = rnd.nextInt(3); // 0~2 까지 랜덤
 
            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();
    }

    @Override
    public String sendMessage(String to) throws Exception {
        MimeMessage message = createMimeMessage(to);

        try {
            sender.send(message);
        }catch(MailException me) {
            me.printStackTrace();
        }
        return authPw;
    }
}

 

createMimeMessage(String to)

메일 발송 시 보여질 내용을 설정하는 메서드

가장 중요한 포인트는 MimeMessage message = sender.createMimeMessage(); 라는 내용입니다.

 

sender는 private JavaMailSender sender; 를 사용한거고 JavaMailSender 는 

EmailConfig 클래스파일에서 기본적으로 Spring이 JavaMailSender 인터페이스를 구현한 JavaMailSenderImpl 를인스턴스 생성하여 host, port 등 기본적인 값을 설정했다.

생성한 MimeMessage 에 이메일에 보여질 본문 내용을 setText() 설정을 하고 setFrom() 을 통해 메일보내는

사람을 설정한다.

 

createAuthKey()

메일인증을 위한 인증코드를 생성하는 메서드

 

sendMessage(String to)

메일발송을 하는 메서드

JavaMailSender 의 send() 메서드를 통해 메일을 발송한다.

JavaMailSender 인터페이스를 구현한 JavaMailSenderImpl 의 send() 메서드는 아래와 같다.

createMimeMessage() 메서드를 통해 설정한 MimeMessage와 함께 send 메서드를 호출한다.

send() 메서드는 doSend() 메서드를 통해 메일을 발송한다.

위 이미지는 JavaMailSenderImpl 클래스의 doSend() 메서드입니다.

실제적으로 메일을 발송하는 메서드이며 Transport 를 사용하여 메일을 발송한다.

 

transport 객체를 null 체크 후 null일 경우 connectTransport() 메서드를 호출하여 설정한다.

 

 

기존 EmailConfig 에서 JavaMailSenderImpl 클래스에 설정한 host, port, username, password 정보를 설정해주고

return 해준다.

 

 

MailSenderService 에서 설정한 MimeMessage 를 가지고 sendMessage 메서드를 호출하여 메일을 발송한다.

 

4. 메일 발송을 위한 Controller 작성

작성한 MailSenderService 를 사용하기 위해 Contorller 에 의존성주입을 해준다.

의존성주입엔 여러가지의 방법이 있으나 본인은 Controller의 생성자를 이용해 생성자주입 방식을 사용합니다.

 

이제 sender 를 사용해보면 아래와 같습니다.

View 에서 넘어온 email 데이터를 sender 의 sendMessage(email)를 통해 메일을 발송한다.

 

아래는 View 내용이다.

signupMain.html

<button> 태그의 onclick 속성에 authMailSend() 함수를 집어넣는다.

authMailSend() 함수를 살펴보면 아래와 같다.

입력받은 input 태그 값을 불러와 email 형식인지 정규표현식을 통해 확인하고 맞으면

아까 생성한 Controller로 이메일을 객체로 담아 POST 요청을 보낸다.

 

그럼 아래와 같이 정상적으로 메일이 도착한걸 볼 수 있습니다.

 

naver 메일로 메일 발송 후 확인한 모습이다.

 

끄읏!

728x90
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.