[SpringBoot] SMTP 이메일 인증 (네이버)

smlee·2022년 7월 7일
0

SpringBoot - JDBC

목록 보기
2/8

프로젝트를 하던 도중 회원가입 과정에서 이메일 인증이 필요했다.
처음에는 SMTP 메일 전송을 구글로 하려고 하였다. 이를 위해서는 보안 수준이 낮은 앱의 액세스를 허용해주어야 했다.

따라서 Google 계정으로 들어가 보안 수준이 낮은 앱의 액세스를 허용해주려고 하였는데

이러한 화면이 나왔다. 이 설정은 더 이상 사용할 수 없다는 안내문이 나와 이에 대해 알아보기 위하여 자세히 알아보기를 클릭하니


1달 조금 전부터 로그인 하도록 하는 것을 방지하고 있다는 내용이었다.

따라서 구글 대신 네이버를 사용하여 이메일 인증을 진행하려 한다.

1. 네이버 메일 설정


네이버 메일의 좌측 하단의 환경 설정을 누른다.

그러면 위와 같은 창이 뜨는데, 여기서 POP3/ IMAP 설정 탭에 들어간다.

그리고 위와 같이 POP3/SMTP 사용을 누르고 위와 같이 설정을 시킨다.

설정을 저장하면 위와 같이 환경 설정 안내 화면이 밑에 작게 뜬다.

2. 스프링부트

(1) 환경 설정

Gradle

implementation 'org.springframework.boot:spring-boot-starter-mail'

Maven

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

그리고 Config 파일을 추가한다.
application.yml에 추가해도 되지만, 현재 진행하고 있는 프로젝트에서 Config 파일들을 관리하는 디렉터리가 있으므로 MailConfig.java라는 파일을 만들어주었다.

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

        javaMailSender.setHost("smtp.naver.com");
        javaMailSender.setUsername("네이버 SMTP 설정 이메일");
        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");
        properties.setProperty("mail.smtp.starttls.enable", "true");
        properties.setProperty("mail.debug", "true");
        properties.setProperty("mail.smtp.ssl.trust","smtp.naver.com");
        properties.setProperty("mail.smtp.ssl.enable","true");
        return properties;
    }
}

위의 내용들은

아까 설정해줬던 내용들을 그대로 옮기기만 하면 되는 것이다.

(2) Controller, Service 작성

먼저 MailService.java를 작성하였다.

private MimeMessage createMessage(String    code, String email) throws Exception{
        MimeMessage message = javaMailSender.createMimeMessage();

        message.addRecipients(Message.RecipientType.TO, email);
        message.setSubject("오늘의 집 모의외주 프로젝트 인증 번호입니다.");
        message.setText("이메일 인증코드: "+code);

        message.setFrom(new InternetAddress(Secret.RECIPIENT));

        return  message;
    }

    public void sendMail(String code, String email) throws Exception{
        try{
            MimeMessage mimeMessage = createMessage(code, email);
            javaMailSender.send(mimeMessage);
        }catch (MailException mailException){
            mailException.printStackTrace();
            throw   new IllegalAccessException();
        }
    }
    
    public long sendCertificationMail(String    email)  throws BaseException {
        if(userProvider.checkEmail(email) == 1){
            throw   new BaseException(BaseResponseStatus.DUPLICATED_EMAIL);
        }
        try{
            String  code = UUID.randomUUID().toString().substring(0, 6);
            sendMail(code, email);

            return  mailDao.createVerificationCode(code, email);
        }catch (Exception exception){
            exception.printStackTrace();
            throw   new BaseException(BaseResponseStatus.DATABASE_ERROR);
        }
    }

createMessage라는 함수로 메일로 보낼 내용들을 생성한다. 그후 sendMail 메서드를 이용하여 실제로 이메일을 보낸다.

위 코드는 인증 코드 보내기에 사용된 메서드들이다. UUID를 사용하여 인증 코드를 발생시켰고, 해당 코드를 사용자에게 전송해주는 코드이다.

그리고 컨트롤러에서 메일을 보낼 예정이다.

@ResponseBody
    @PostMapping("")
    public BaseResponse<Long>        sendEmail(@RequestBody String data)  throws BaseException{
        JSONObject  parser = new JSONObject(data);
        String      email = parser.getString("email");

        if(email == null){
            return  new BaseResponse<>(BaseResponseStatus.POST_USERS_EMPTY_EMAIL);
        }

        if(!ValidationRegex.isRegexEmail(email)){
            return  new BaseResponse<>(BaseResponseStatus.POST_USERS_INVALID_EMAIL);
        }

        try{

            mailService.sendCertificationMail(email);

            long    verifyCodeId = mailService.sendCertificationMail(email);

            return  new BaseResponse<Long>(verifyCodeId);
        }
        catch (BaseException baseException){
            return  new BaseResponse<>(baseException.getStatus());
        }
    }

JSON 형태로 데이터를 받는 과정에서 JSON 파싱을 통해 원하는 정보인 이메일을 추출한 뒤, 메일을 보내도록 하는 코드이다.

인증번호 조회를 위해 DB에 정보가 업데이트 되므로 POST 메서드를 사용하였다.

이 코드들을 실행시키면

원하는 코드들을 제대로 받을 수 있다.

1개의 댓글

comment-user-thumbnail
2022년 11월 1일

BaseException은 직접 만든 Exception 일까요?

답글 달기