이메일 인증 코드 보내기(SpringBoot, SMTP)

김건우·2023년 2월 3일
0

spring

목록 보기
6/9
post-thumbnail

회원 가입 이후 이메일 인증을 한 사용자에게만 서비스 접근을 할 수 있도록 구현하고 싶어 찾아본 결과 구글에서 제공하는 SMTP 서비스를 통해 비교적 쉽게 구현할 수 있었다. 단, 구글 SMTP 서비스는 한 이메일 당 하루 100건씩 제한을 걸기 때문에 로컬에서 여러 번 테스트하고 싶을 때는 실제 메일을 보내지 않고 콘솔에 메일 내용을 로그로 작성하는 것을 추천한다.

application-dev.yml

spring :
  mail :
    host : smtp.gmail.com
    port : 587
    username : [본인 Gmail email]
    password : [비밀번호]
    properties :
      mail :
        smtp :
          auth : true
          starttls :
            enable : true

build.gradle

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-mail'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    ....
}

위와 같이 .yml에 구글에서 받은 앱 비밀번호와 자신의 GMAIL계정을 적고
build.gradle에 의존성을 주입해준다. 현재 목표는 개발환경과 로컬환경에서 각각 다르게 메일을 보낼 것이다.

개발환경

: 개발환경(DEV) SMTP를 이용하여 회원가입한 이메일로 직접 인증 메일을 보내줄 것 이다.

로컬환경

:로컬환경(local) 에서는 에서는 메일을 전송하지않고 콘솔창에 메일과 이메일 토큰을 보내줄 것이다.

결론 : EmailService의 추상화가 필요하다.

EmailService.interface

개발환경과 로컬환경에서 재정의할 sendEmail() 메서드

public interface EmailService {
    void sendEmail(EmailMessage emailMessage);
}

EmailMessage(DTO)

이메일을 보내기 위한 DTO

@Data
@Builder
public class EmailMessage {
    //수신자
    private String to;
    //제목
    private String subject;
    //내용
    private String message;
}

로컬환경에서의 email발송

콘솔에 해당 이메일과 이메일 인증토큰을 발급 받을것이다.

@Profile

스프링에서는 프로필(Profile)을 통해 런타임 환경을 설정할 수 있는 기능을 제공한다. 이 기능을 이용하여 테스트환경에서 여러 테스트를 돌리고 난 다음 프로덕션 환경으로 전환하는 것을 어렵지 않게 할 수 있다.아래를 보면 @Profile("local")을 볼 수 있는데 local 환경에서 동작한다는 어노테이션이다.🔽

/**local에서 개발할 때**/
@Slf4j
@Profile("local")
@Component
public class ConsoleEmailService implements EmailService{

    @Override
    public void sendEmail(EmailMessage emailMessage) {
        log.info("sent email: {}", emailMessage.getMessage());
    }
}

DEV환경에서의 Html email 발송

직접 html 템플릿을 개발하여 인증 이메일을 발송해줄 것이다.

@Slf4j
@Profile("dev")
@Component
@RequiredArgsConstructor
public class HtmlEmailService implements EmailService {

    private final JavaMailSender javaMailSender;

    @Override
    public void sendEmail(EmailMessage emailMessage) {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "UTF-8");
            mimeMessageHelper.setTo(emailMessage.getTo());
            mimeMessageHelper.setSubject(emailMessage.getSubject());
            mimeMessageHelper.setText(emailMessage.getMessage(), true);
            javaMailSender.send(mimeMessage);
            log.info("sent email: {}", emailMessage.getMessage());
        } catch (MessagingException e) {
            log.error("failed to send email", e);
            throw new RuntimeException(e);
        }
    }
}

회원가입시 이메일을 보내주는 Service layer

  • TemplateEngine을 주입받아서 templateEngine.process("mail/simple-link", context)로 첫번째 인자 : html , 두번째 인자 : model과 같은 역할
  • 타임리프 템플릿을 사용할 것이기 때문에 context.setVariable()을 사용하여 view단에 값을 넘겨 줄 것이다.
@Service
@Transactional
@Slf4j
@RequiredArgsConstructor
public class AccountService implements UserDetailsService {

 private final EmailService emailService;
 private final TemplateEngine templateEngine;
 
 
  /**
     * 이메일에 token보내는 메서드
     **/
    public void sendSignUpConfirmEmail(Account newAccount) {
        Context context = new Context();
        context.setVariable("link", "/check-email-token?token=" + newAccount.getEmailCheckToken() +
                "&email=" + newAccount.getEmail());
        context.setVariable("nickname", newAccount.getNickname());
        context.setVariable("linkName", "이메일 인증하기");
        context.setVariable("message", "스터디히어 서비스를 사용하려면 링크를 클릭하세요.");
        context.setVariable("host", appProperties.getHost());
        String message = templateEngine.process("mail/simple-link", context);

        EmailMessage emailMessage = EmailMessage.builder()
                .to(newAccount.getEmail())
                .subject("스터디히어, 회원 가입 인증")
                .message(message)
                .build();

        emailService.sendEmail(emailMessage);
    }

회원가입 인증 메일

1.회원가입 인증 메일을 보내준 것을 확인할 수 있다.🔽

2.다음과 같이 이메일 인증 확인할 수 있다.🔽

profile
Live the moment for the moment.

0개의 댓글