회원 비밀번호 찾기 기능: Spring Boot + Gmail SMTP 예제

박성현·2025년 12월 3일

개발중 학습

목록 보기
33/43

🚀 Spring Boot – Gmail SMTP 로 임시 비밀번호 메일 보내기 구현하기

회원 비밀번호 찾기 기능을 만들 때, 임시 비밀번호를 생성하고 이메일로 발송하는 기능은 많은 서비스에서 필요한 로직입니다.
이번 글에서는 Spring Boot에서 Gmail SMTP를 이용해 이메일을 보내는 방법과 임시 비밀번호 생성/업데이트 흐름까지 모두 정리합니다.


1. 📦 이메일 전송을 위한 의존성 추가

이메일 전송을 위해서는 spring-boot-starter-mail 의존성이 필요합니다.

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

이 의존성을 통해 JavaMailSender, MimeMessage, MimeMessageHelper 등을 사용할 수 있게 됩니다.


2. ⚙️ Gmail SMTP 설정 (application.properties)

# Gmail SMTP 기본 설정
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=YOUR_GMAIL_ADDRESS
spring.mail.password=YOUR_APP_PASSWORD
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.ssl.trust=smtp.gmail.com
spring.mail.properties.mail.transport.protocol=smtp
옵션역할
spring.mail.hostGmail SMTP 서버 주소
spring.mail.portSMTP 포트 (TLS: 587)
spring.mail.usernameGmail 계정 이메일
spring.mail.password앱 비밀번호
mail.smtp.authSMTP 로그인 인증 사용
mail.smtp.starttls.enableTLS 보안 연결 활성화
mail.smtp.starttls.requiredTLS 필수 적용
mail.smtp.ssl.trustGmail 인증서 신뢰
mail.transport.protocolSMTP 프로토콜 사용

⚠️ Gmail은 실제 비밀번호를 넣으면 안 되고
Google 앱 비밀번호(App Password)를 발급받아 사용해야 합니다.
앱 비밀번호 발급방법은 제 블로그에 추가적으로 작성해뒀습니다 !


3. 🔐 임시 비밀번호 생성 + 이메일 발송 + 비밀번호 업데이트 로직

임시 비밀번호를 생성하고, 해당 비밀번호를 사용자 DB에 업데이트한 뒤, 이메일로 발송하는 핵심 로직입니다.

📌 sendPasswordByEmail() — 메일 발송 메서드

private boolean sendPasswordByEmail(String toEmail, String userId, String userName) {

    try {
        // 6자리 임시 비밀번호 생성
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        StringBuilder sb = new StringBuilder();
        Random random = new Random();

        for (int i = 0; i < 6; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        String tempPassword = sb.toString();

        // DB 비밀번호 업데이트
        Map<String, Object> updateParam = new HashMap<>();
        updateParam.put("m_user_id", userId);
        updateParam.put("m_user_pw", tempPassword);
        testMapper.updateUserPassword(updateParam);

        // 메일 생성
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

        helper.setFrom("발신자 이메일 주소");
        helper.setTo(toEmail);
        helper.setSubject("임시 비밀번호 안내");

        String htmlContent =
                "<html><body>" +
                "<h3>임시 비밀번호 안내</h3>" +
                "<p>안녕하세요, " + userName + "님.</p>" +
                "<p>요청하신 임시 비밀번호는 다음과 같습니다.</p>" +
                "<h2>" + tempPassword + "</h2>" +
                "<p>로그인 후 반드시 비밀번호를 변경해주세요.</p>" +
                "</body></html>";

        helper.setText(htmlContent, true);
        mailSender.send(message);

        return true;

    } catch (Exception e) {
        return false;
    }
}

4. 🧩 비밀번호 찾기 서비스 로직

DB 조회 후 사용자 이메일이 확인되면 sendPasswordByEmail()을 호출합니다.

@Override
public ApiResult findUserPw(Map<String, Object> param) {

    ApiResult apiResult = ApiResult.builder()
            .status(ApiResult.STATUS_SUCCESS)
            .build();

    try {
        // 입력값 검증
        if (param.get("m_user_id") == null 
            || param.get("m_user_id").toString().trim().isEmpty()) {
            return apiResult;
        }

        if (param.get("m_user_email") == null 
            || param.get("m_user_email").toString().trim().isEmpty()) {
            return apiResult;
        }

        // DB 조회
        List<Map<String, Object>> resultList = testMapper.findUserPwCheck(param);

        if (resultList != null && !resultList.isEmpty()) {
            Map<String, Object> row = resultList.get(0);

            String userId = (String) row.get("user_id");
            String userEmail = (String) row.get("user_email");
            String userNm = (String) row.get("user_nm");

            // 이메일 전송
            if (userEmail != null) {
                boolean emailSent = sendPasswordByEmail(userEmail, userId, userNm);

                if (!emailSent) {
                    return apiResult;
                }
            }

            apiResult.setData("rsData", resultList);
        }

    } catch (Exception ex) {
        apiResult.setStatusMsg(ApiResult.STATUS_ERROR, "시스템 오류가 발생했습니다.");
    }

    return apiResult;
}

5. 🧩 MimeMessage / MimeMessageHelper가 하는 역할

클래스역할
MimeMessage이메일 메시지 객체(본문, 첨부파일, HTML 지원)
MimeMessageHelperMimeMessage를 쉽게 조작하기 위한 도우미 클래스

예시

MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
  • true → HTML/첨부파일(멀티파트) 허용
  • "UTF-8" → 문자열 인코딩 설정

📌 마무리

이번 글에서 정리한 내용:

  • Spring Boot에서 Gmail SMTP 설정 방법
  • 임시 비밀번호 생성 로직
  • DB 비밀번호 업데이트 코드
  • HTML 이메일 발송 구현
  • MimeMessage / Helper 동작 원리

비밀번호 찾기는 단순한 기능 같지만
보안, 성능, UI까지 신경 써야 할 요소들이 많기 때문에
정석대로 구현해두면 이후 기능 확장에도 도움이 됩니다.


profile
개발기록장

0개의 댓글