0105

1. MatzipWithYou Java/Spring 이메일 인증 구현(1) (MyBatis, Redis, Thymeleaf, STMP설정) 본문

✏️ Project/MatzipWithYou

1. MatzipWithYou Java/Spring 이메일 인증 구현(1) (MyBatis, Redis, Thymeleaf, STMP설정)

공백오 2025. 3. 12. 16:24
728x90
반응형

✅ 결과

 

✅ 코드 로직

✔️ 이메일 창에 입력한 이메일로 인증번호를 보낸다

✔️ 이메일과 인증번호를 Redis에 3분간 저장한다.

✔️ 입력된 인증번호와 Redis에 저장된 인증번호가 같은지 확인한다.

✔️ 같으면 Redis에서 인증번호와, 이메일을 삭제한다.

 

✅ STMP설정

 

spring:
  application:
    name: 

  #STMP
  mail:
    host: smtp.gmail.com
    port: 587
    username: "yourEmail@gmail.com"
    password: "앱 비밀번호"
    properties:
      mail:
        smtp:
          starttls:
            enable: true
          auth: true

✅ Controller ("/sendEmail")

@GetMapping("/sendEmail")
@ResponseBody  // 이 어노테이션으로 JSON 형식 응답을 반환
public ResponseEntity<Map<String, String>> sendEmail(@RequestParam String email) {


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

    // 이메일 형식 검증
    String emailPattern = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
    if (email == null || email.trim().isEmpty()) {
        response.put("error", "이메일은 필수입니다.");
        return ResponseEntity.badRequest().body(response);
    } else if (!email.matches(emailPattern)) {
        response.put("error", "유효하지 않은 이메일 형식입니다.");
        return ResponseEntity.badRequest().body(response);
    }

    try {
        EmailMessage emailMessage = new EmailMessage();
        emailMessage.setTo(email);          // 수신자 이메일 설정
        emailMessage.setSubject("이메일 인증");  // 이메일 제목 설정

        memberService.createEmail(emailMessage);  // 이메일 발송
        response.put("message", "인증 이메일이 전송되었습니다.");
        System.out.println("response: " + response);
        return ResponseEntity.ok(response);  // 성공시 JSON 응답
    } catch (Exception e) {
        e.printStackTrace();
        response.put("error", "이메일 전송에 실패했습니다. 다시 시도해주세요.");
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);  // 에러 시 JSON 응답
    }

}

 

📌 memberService.createEmail(emailMessage)

✔️ 코드 개요

  • 6자리 랜덤 인증번호 생성 (createNumber())
  • Redis에 인증번호 저장 (emailAuthService.storeAuthCode(email, number))
  • 이메일 객체 생성 (MimeMessage)
  • 이메일 제목 & 수신자 설정
  • Thymeleaf를 사용해 이메일 본문을 HTML로 구성
  • 이메일을 HTML 형식으로 설정 (setText(body, true))
  • 이메일 전송 (mailSender.send(message))
  • 예외 발생 시 로그 출력
@Override
public MimeMessage createEmail(EmailMessage email) {
    createNumber(); // 숫자 생성

    //인증번호 저장
    emailAuthService.storeAuthCode(email.getTo(), String.valueOf(number));


    MimeMessage message = mailSender.createMimeMessage();
    try {
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true, "UTF-8");
        mimeMessageHelper.setTo(email.getTo());
        mimeMessageHelper.setSubject(email.getSubject());

        // Thymeleaf 템플릿 처리
        Context context = new Context();
        context.setVariable("number", String.valueOf(number)); // 템플릿에 값 전달
        context.setVariable("to", email.getTo());

        // auth-email-template.html 템플릿을 Thymeleaf로 처리하여 HTML 내용을 생성
        String body = templateEngine.process("auth-email-template", context);

        mimeMessageHelper.setText(body, true); // HTML로 이메일 본문 설정

        // 이메일 전송
        mailSender.send(message);
    } catch (MessagingException e) {
        e.printStackTrace();
    }

    return message;

}

 

1️⃣  emailAuthService.storeAuthCode(이메일, 인증번호)

✔️emailAuthSevice.sotreAuthCode(email.getTo(), String.valuof(number));

✔️ storeAuthCode(이메일,인증번호)를 호출하여 이메일과 해당 인증번호를 저장

✔️ 보통 Redis같은 인메모리 DB를 사용하여 일정시간 동안만 인증번호를 유지한다.

 

2️⃣ storeAuthCode(String email, String authCode)

 

✔️ 이메일과 인증번호를 Redis에 저장하는 메서드이다.

✔️ 사용자가 이메일 인증을 요청하면, 랜덤한 인증번호를 생성하여 Redis에 일정기간 동안 저장합니다.

// 인증번호 저장
@Override
public void storeAuthCode(String email, String authCode) {


    // auth-code:aaaaaaa@gmail.com <- 이런식으로 authCode가 작성이 된다.(key)

    try {
        redisTemplate.opsForValue().set(PREFIX + email, authCode, 3, TimeUnit.MINUTES);
        // 값이 성공적으로 설정됨
        System.out.println("성공적으로 저장 되었습니다 " + email + " 인증번호 : " + authCode);
    } catch (Exception e) {
        // 값 설정 실패
        System.out.println("실패: " + e.getMessage());
    }
}

 

이런식으로 로그를 찍었다.

3️⃣ MimeMessage. 이메일 메세지 객체 생성

✔️ mailSender.createMimeMessage() -> 이메일 객체 생성

✔️ MimeMessageHelper을 사용하여 이메일 정보를 설정

    • setTo(email.getTo()) → 받는 사람 설정
    • setSubject(email.getSubject()) → 이메일 제목 설정
    • true → HTML 형식 이메일을 사용할 수 있도록 설정
    • "UTF-8" → 문자 인코딩을 설정하여 한글이 깨지지 않도록 함

 

4️⃣ Thymeleaf를 이용한 이메일 본문 HTML 생성

✔️ Context 객체를 생성하여 이메일 본문에서 사용할  데이터(변수)를 저장

✔️ context.setVariable("number", String.valueOf(number)) // 인증번호

✔️ context.setVariable("to", email.getTo()) // 사용자의 이메일 주소

5️⃣ Html 이메일 본문 생성

✔️templateEngine.process("auth-email-template", context);

✔️ Thymeleaf 템플릿("auth-email-template.html)을 사용하여 이메일 본문 생성

✔️ context에 저장된 변수들이 템플릿 내에서 치환된다.

 

6️⃣ 이메일 본문을 HTML로 설정

✔️ mimeMessageHelper.setText(body, true)

✔️ setText(body, true)

✔️ body -> Thymeleaf에서 생성된 HTML코드

✔️ true -> 이메일을 HTML형식으로 설정 -> HTML을 적용하지 않으면 일반텍스트로 전송됨

 

7️⃣ 이메일 전송

✔️ mailSender.send(message)

✔️ 메일을 실제로 발송하는 부분

✔️ JavaMailSender 인터페이스를 사용하여 SMTP 서버를 통해 이메일 전송

 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="ko">
<head>
    <meta charset="UTF-8">
    <title>인증 이메일</title>
</head>
<body>
<div class="container">
    <h3 th:text="'안녕하세요, ' + ${to} + '님!'"></h3>
    <h3>요청하신 인증 번호입니다:</h3>
    <h1 th:text="${number}"></h1>
    <h3>감사합니다.</h3>
</div>
</body>
</html>

 

 


templateEngine Thymeleaf 템플릿 엔진 - HTML 이메일 본문을 동적으로 생성
mimeMessageHelper 이메일 작성 도우미 - 제목, 본문, 수신자 설정을 쉽게 도와줌
mailSender JavaMailSender - SMTP 서버를 통해 이메일을 실제로 전송
context Thymeleaf 변수 저장소 - 템플릿에서 사용할 데이터를 저장

✅ 후기

  •  첫번째 프로젝트였어서 코드를 막 생각없이 짜서 읽기가 어렵다. 
  •  MVC 패턴을 너무 못지켰다.
  • 다음에 짜면 변수명을 좀 더 직관적으로..
728x90