오봉이와 함께하는 개발 블로그

비밀번호 찾기 이메일 전송 [JavaMailSender(SimpleMailSender, MimeMessage)] 본문

Artineer 리뉴얼 프로젝트

비밀번호 찾기 이메일 전송 [JavaMailSender(SimpleMailSender, MimeMessage)]

오봉봉이 2022. 9. 28. 22:15
728x90

기능 소개

간단하게 설명하면 비밀번호를 찾을 때 아이디와 이메일을 입력하면 입력한 정보를 토대로 DB에서 Member를 찾고 해당 이메일로 비밀번호를 변경해서 이메일을 보내준다.

JavaMailSender

메일 전송은 스프링에서 제공하는 JavaMailSender를 사용한다.
JavaMailSenderSimpleMailSenderMimeMessage를 지원하는데 간략하게 설명하면 SimpleMailSender는 말 그대로 심플한 메시지 자체만을 메일로 전송할 때 사용하는 메소드이고, MimeMessage는 파일 첨부나 HTML로 구성할 때 사용한다.

@Component
@RequiredArgsConstructor
public class MailService {

    private final JavaMailSender javaMailSender;

    // 개행 문자
    private static final String newLine = System.getProperty("line.separator");
    ....
}

SimpleMailSender

먼저 해당 메소드를 이용해서 보냈으나, 커스텀 할 수 있는 부분이 너무 적어서 밋밋하다는 느낌이 들었기 때문에 결론적으로는 MimeMessage을 사용했다.
일단 SimpleMailSender의 코드부터 보자.

    public String sendMail(List<String> users, String memberId) {
        List<String> userList = new ArrayList<>();

        for (String user : users) {
            userList.add(user);
        }

        int userSize = userList.size();

        SimpleMailMessage simpleMessage = new SimpleMailMessage();

        simpleMessage.setTo((String[]) userList.toArray(new String[userSize]));

        simpleMessage.setFrom("admin@artineer.net");

        simpleMessage.setSubject("[We Are Artineer!] " + memberId + " 님의 임시 비밀번호 입니다.");

        String temporaryPassword = temporaryPassword();
        simpleMessage.setText(temporaryPassword);

        javaMailSender.send(simpleMessage);

        return temporaryPassword;
    }

파라미터로 컨트롤러에서 List를 하나 받는다.

// Controller

List<String> userMail = new ArrayList<>();
userMail.add(memberEmail);

파라미터로 넘어오는 이메일을 List로 만들어서 넘겨준다.
이 List는 setTo에 들어가서 수신자가 된다.

memberId는 그냥 임시 비밀번호를 요청한 ID를 알려주기 위해 받는 파라미터다.
temporaryPassword();는 알파벳 대,소문자와 숫자를 조합해서 만든 6자리 랜덤 비밀번호를 만드는 메소드다.
setFrom을 통해서 발신 이메일을 바꿔보려 했지만, 바뀌지 않았다. 바꾸는 방법을 아시는 분은 댓글 부탁드립니다...

application.properties

# mail 보내기
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.auth=true

해당 설정은 아래 링크를 참고 바랍니다.

결과 화면

MimeMessage

SimpleMailSender을 사용했지만, 결과 화면이 너무 밋밋해서 해당 메소드로 변경했다.

    public String sendMessage(String memberId, String email) throws MessagingException {
        Properties props = System.getProperties();

        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.port", MailServiceConst.PORT);
        props.put("mail.smtp.starttls.enable", MailServiceConst.STARTTLS_ENABLE);
        props.put("mail.smtp.auth", MailServiceConst.AUTH);

        Session session = Session.getDefaultInstance(props);


        MimeMessage mimeMailMessage = new MimeMessage(session);

        mimeMailMessage.setFrom("admin@artineer.net");

        mimeMailMessage.setRecipients(Message.RecipientType.TO, email);

        mimeMailMessage.setSubject("[We Are Artineer!] " + memberId + " 님의 임시 비밀번호 입니다.", "UTF-8");

        // 임시 비밀번호
        String tempPassword = temporaryPassword();

        mimeMailMessage.setContent(createContent(memberId, tempPassword), "text/html;charset=UTF-8");

        // 메일 전송
        Transport transport = session.getTransport();

        try {
            transport.connect(MailServiceConst.HOST, MailServiceConst.USERNAME, MailServiceConst.PASSWORD);
            transport.sendMessage(mimeMailMessage, mimeMailMessage.getAllRecipients());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            transport.close();
        }

        return tempPassword;
    }

프로퍼티에 해당 설정 정보를 넣어서 세션에 넣은 후 MimeMessage를 생성한다.
마찬가지로 setFrom을 통해서 발신자 이메일을 변경하려 했으나 되지 않았다. 방법을 아시는 분은.... 마찬가지로 댓글 부탁드립니다...
setRecipients는 수신자를 설정한다.

파라미터 email은 마찬가지로 수신자에 들어갈 이메일이고 컨트롤러에서 입력한다.
파라미터 memberId는 메일 제목과 내용에 넣기 위해 받는 파라미터다. 아래 결과 화면을 참고하자.
마찬가지로 temporaryPassword();는 알파벳 대,소문자와 숫자를 조합해서 만든 6자리 랜덤 비밀번호를 만드는 메소드다.
반환 값으로 tempPassword을 던져주는데, 컨트롤러에서 비밀번호를 변경해준다.

    public String createContent(String memberId, String tempPassword) {
        String content = String.join(
                newLine,
                "<h1>[We Are Artineer!]</h1>",
                "<hr>",
                "<b>" + memberId + "</b>" + "님이 요청하신 임시 비밀번호 입니다.",
                "<h2>" + tempPassword + "</h2>"
                );

        return content;
    }

mimeMailMessage.setContent(createContent(memberId, tempPassword), "text/html;charset=UTF-8");
createContent로 내용을 만들었다.

newLine은 글 최상단에 있으니 참고하자.

MailServiceConstSimpleMailSender에서 설정한 properties가 적용되지 않아서 따로 입력했다.

public class MailServiceConst {
    // 메일 세팅 정보
    public static final String HOST = "smtp.gmail.com";
    public static final Integer PORT = 587;
    public static final String USERNAME = "ID";
    public static final String PASSWORD = "앱 비밀번호";
    public static final String STARTTLS_ENABLE = "true";
    public static final String AUTH = "true";
}

transport는 메일을 보내는 메소드니 자세한 내용은 JavaMailSender를 참고하자.

결과 화면

MimeMessage 수정

MailServiceConstSimpleMailSender에서 설정한 properties가 적용되지 않아서 따로 입력했다.

public class MailServiceConst {
    // 메일 세팅 정보
    public static final String HOST = "smtp.gmail.com";
    public static final Integer PORT = 587;
    public static final String USERNAME = "ID";
    public static final String PASSWORD = "앱 비밀번호";
    public static final String STARTTLS_ENABLE = "true";
    public static final String AUTH = "true";
}

properties가 적용되지 않는 위 문제를 해결하는 코드다.

    public String sendMessage(String memberId, String email) throws MessagingException {

        MimeMessage mimeMessage = javaMailSender.createMimeMessage();

        mimeMessage.setFrom("admin@artineer.net");

        mimeMessage.setRecipients(Message.RecipientType.TO, email);

        mimeMessage.setSubject("[We Are Artineer!] " + memberId + " 님의 임시 비밀번호 입니다.", "UTF-8");

        // 임시 비밀번호
        String tempPassword = temporaryPassword();

        mimeMessage.setContent(createContent(memberId, tempPassword), "text/html;charset=UTF-8");
        javaMailSender.send(mimeMessage);

        return tempPassword;
    }

결과는 똑같고, properties에 적용한 설정이 자동으로 적용된다.

결론

간단하게 보낼 수 있지만, 너무 밋밋해서 MimeMessage를 사용했다.
MimeMessage로도 파일 첨부는 가능하지만, 번거롭다고 하니 파일 첨부가 필요하면 MimeMessageHelper를 사용하자.

728x90
Comments