개인프로젝트/기능프로그램_오늘뭐입지

20240523_메일 시스템(임시비밀번호 전송, 이메일 인증)

일일일코_장민기 2024. 5. 23. 19:40
728x90

React 공부 및 모놀리틱 프로젝트 구현에 시간을 쓰다보니 오랜만에 기능을 추가했다.

 

전체코드

더보기

application.properties

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=이메일
spring.mail.password=이메일 코드
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.auth=true

 

MailController

package org.member.mailController;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequiredArgsConstructor
@Slf4j
public class MailController {

    @Value("${spring.mail.username}")
    private static String from;
    private final MailService mailService;

    private static final String from_email = from;
    private String expiredTime;
    private String authorizationCode;

    @PostMapping("/authorizationCode_Email")
    public void authorizationCode_Email(String to_email) throws IOException {

        Map<String,String> changeData = new HashMap<>();

        //******************복사 후 수정하는 부분******************
        String emailCode = "authorizationCode_Email";
        String email_title = "[회원가입인증] 회원가입 인증번호 전송";
        changeData.put("##인증번호##", authorizationCode);               
        changeData.put("##인증번호_유효기간##", expiredTime);        
        //******************복사 후 수정하는 부분******************

        String email_Form = "static/mailForm/"+emailCode+"_Form.html";
        String innerImageName = emailCode+"_Image";
        String innerImagePath = "/static/mailForm/image/"+innerImageName+".png";

        String email_body = mailService.emailBody(email_Form, changeData);
        mailService.sendEmail(from_email, to_email, email_title, email_body, innerImageName, innerImagePath);
    }


    public void temporaryPassword_Email(String to_email, String temporaryPassword, String username) throws IOException {

        Map<String,String> changeData = new HashMap<>();

        //******************복사 후 수정하는 부분******************
        String emailCode = "temporaryPassword_Email";
        String email_title = "[회원정보변경] 임시 비밀번호 발급";
        changeData.put("##유저_링크##", "www.naver.com");           //임시 링크
        changeData.put("##유저_아이디##", username);
        changeData.put("##유저_비밀번호##", temporaryPassword);
        //******************복사 후 수정하는 부분******************

        String email_Form = "static/mailForm/"+emailCode+"_Form.html";
        String innerImageName = emailCode+"_Image";
        String innerImagePath = "/static/mailForm/image/"+innerImageName+".png";

        String email_body = mailService.emailBody(email_Form, changeData);
        mailService.sendEmail(from_email, to_email, email_title, email_body, innerImageName, innerImagePath);

    }

    @PostMapping("/mailCookie")
    public void mailCookie(HttpServletResponse httpServletResponse){

        authorizationCode = "111111"; //임시 인증번호
        int authorialTime = 180;

        LocalDateTime now = LocalDateTime.now();
        expiredTime = now.plus(Duration.ofSeconds(authorialTime)).toString();

        Cookie cookie = new Cookie("authorizationCode", authorizationCode);
            cookie.setMaxAge(authorialTime);
            httpServletResponse.addCookie(cookie);
    }

    @PostMapping("/checkAuthorizationCode")
    public boolean checkAuthorizationCode(String enteredCode){
        return authorizationCode.equals(enteredCode);
    }

    @PostMapping("/deleteAuthorizataionCodeCookiee")
    public void deleteAuthorizataionCodeCookiee(HttpServletResponse httpServletResponse){
        Cookie cookie = new Cookie("authorizationCode", "");
        cookie.setMaxAge(0);
        httpServletResponse.addCookie(cookie);
    }
}

 

 MailService

package org.member.mailController;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class MailService {

    private final JavaMailSender mailSender;

    public void sendEmail(String fromEmail, String toEmail, String emailTitle, String emailBody, String innerImageName, String innerImagePath) {
        mailSender.send(
                mimeMessage -> {
                    MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);                // true: 멀티파트 메세지를 사용
                    messageHelper.setFrom(fromEmail);
                    messageHelper.setTo(toEmail);
                    messageHelper.setSubject(emailTitle);
                    messageHelper.setText(emailBody, true);                                                        // true: html을 사용
                    messageHelper.addInline(innerImageName, new ClassPathResource(innerImagePath));
                });
    }

    public String emailBody(String emailForm, Map<String, String> changeData) throws IOException {
        ClassPathResource classPathResource = new ClassPathResource(emailForm);
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(classPathResource.getInputStream()));

        String line;
        StringBuilder email_body = new StringBuilder();
        while ((line = bufferedReader.readLine()) != null) {
            for (Map.Entry<String, String> entry : changeData.entrySet()) {
                line = line.replace(entry.getKey(), entry.getValue());
            }
            email_body.append(line);
            email_body.append("\n");
        }
        return email_body.toString();
    }

}

 

 jsp

인증번호: <input type="text" id="authorizationCode"><br>
<input type="button" id="sendEmail" value="인증번호 보내기"><br>
<span id="checkAuthorizationCodeField"></span><br>

 

 js

$(function() {

    //인증번호 쿠키 삭제
    deleteAuthorizataionCodeCookiee()
     $("#email").on("input", function () {
        $("#existEmail").html('')
    })
    //인증번호 칸 입력 시 경고창 삭제
    $("#authorizationCode").on("input", function () {
        $("#checkAuthorizationCodeField").html('')
    })
    //제출 시 재확인 및 경고창 확인
    $("#registerForm").on("submit", function (event) {
        checkUsername()
        checkEmail()
        checkAuthorizationCode()
        if ($("#existUsername").html().trim() !== ""
            || $("#existEmail").html().trim() !== ""
            || $("#checkAuthorizationCodeField").text().trim() !== "확인되었습니다.") {
            event.preventDefault();
        } else {
            $("#registerForm")[0].submit();
        }
    })
})

function send_authorizationCode() {
    const to_email = $("#email").val();
    let authorizationCode = "";
    $.ajax({
        type: "post",
        url: "/mailCookie",
        dataType: "text",
        error: function () {
            console.log("인증번호 발급 에러")
        }
    });
    $.ajax({
        type: "post",
        url: "/authorizationCode_Email",
        data: {
            to_email: to_email
        }
    });
}

function checkAuthorizationCode() {
    const authorizationCode = $("#authorizationCode").val()
    const checkAuthorizationCodeField = $("#checkAuthorizationCodeField")
    $.ajax({
        type: "post",
        url: "/checkAuthorizationCode",
        data: {
            enteredCode: authorizationCode
        },
        success: function (response) {
            if (response === true) {
                checkAuthorizationCodeField.html("확인되었습니다.").css("color", "black");
            } else {
                checkAuthorizationCodeField.html("인증번호가 다릅니다.").css("color", "red");
            }
        },
        error: function () {
            console.log("인증번호 미발송")
        }
    })
}

function deleteAuthorizataionCodeCookiee() {
    $.ajax({
        type: "post",
        url: "/deleteAuthorizataionCodeCookiee",
        success: function () {
            console.log("쿠키 삭제 성공")
        },
        error: function () {
            console.log("쿠키 삭제 실패")
        }
    })
}

 

MemberService

mailController.temporaryPassword_Email(memberVO.getEmail(), newPassword, memberVO.getUsername());

 

사실 팀프로젝트 때 쓰던 것과 별 다른게 없다...

 

https://minkee95.tistory.com/140

 

스프링 부트 팀플) 20240310_이메일 시스템 구축

자고 일어나자 마자 암호화/복호화 시스템 한번 보고 이메일 시스템 구축에 들어갔다. 암호화 자체는 잘 되지만, 어제랑 달리 암호가 어째서인지 바뀌진 않는다. 안 되는 건 아니지만, 뭔가 짜게

minkee95.tistory.com

https://minkee95.tistory.com/141

 

스프링 부트 팀플) 20240310_이메일 인증 구현

우선 컨트롤러에 다 때려박았던 코드를 서비스로 분산했다. 이메일 인증 시스템을 위해서는 크게 6가지 작업이 필요하다. 1. 6자리 랜덤 정수를 만드는 함수 2. 그 6자리 정수를 3분만 유효한 쿠키

minkee95.tistory.com

https://minkee95.tistory.com/163

 

스프링 부트 팀플) 20240312_Resource에 있는 이메일.html 사용하기

https://komas.tistory.com/142 [Spring] 스프링 Resources 파일 읽기, 복사 resoruces에 위치한 data.json을 읽어야 한다. { "hello": "123" } data.json의 내용은 다음과 같다. @SpringBootApplication public class RestApIsApplication { pub

minkee95.tistory.com

https://minkee95.tistory.com/175

 

스프링 부트 팀플) 20240313_이메일 시스템 완성

MailController 일부 //단순 메일 전송 @PostMapping("/joinEmail") public String joinEmail(String userEmail, String userName) throws Exception { String authNumber = makeRandomNumber(); Map changeData = new HashMap(); System.out.println(userEmail); Sys

minkee95.tistory.com