이메일 인증 구현하기_v2 : Bean 주입

김재현·2024년 1월 6일
0

TIL

목록 보기
70/88
post-thumbnail

이메일 인증 구현하기_v2 (문제 해결과정)

이전에 '회원가입시 이메일인증 구현하기'를 포스팅 한 바가 있다. 오늘은 프로젝트에 이메일 인증을 시도했는데, 이전과 달리 애먹었던 점이 있어 추가적으로 포스팅한다.

1. javaMailSender 의 Bean 주입

저번처럼 EmailService를 구현하기 위해 javaMailSender를 사용하려 하였더니,
"Could not autowire. No beans of 'JavaMailSender' type found. "
라는 에러메세지와 함께 메일이 보내지지 않았다.

설정에 문제는 없었으므로, Bean 주입이 제대로 되지 않았구나 싶었다.

그래서 직접 Bean 주입을 위해 MailConfig 를 추가했다.

MailConfig

@Configuration
public class MailConfig {

    @Bean
    public JavaMailSender javaMailSender() {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        // 필요한 설정들을 추가
        return mailSender;
    }
}

처음엔 Bean만 주입하면 된다고 생각하고 특별한 설정을 추가하지 않았다.

하지만 이렇게 Bean 주입이 되었는데도 메일이 보내지지 않았다.

에러메세지

Mail server connection failed. Failed messages: org.eclipse.angus.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 25; timeout -1;

포트번호가 안맞기 때문에 연결이 안되었다는데, 나는 아래와 같이 설정했기 때문에 25번 포트를 쓴적이 없는데..?

application.properties

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=${Email_Adress}
spring.mail.password=${APP_Password}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

설정에서 25번으로 바꿔보기도 하였지만 여전히 연결이 불가하였다.

2. Config 에 설정 직접 주입

이것저것 찾아보다가 포트번호 등 설정이 제대로 적용되지 않는다고 판단하였고, MailConfig에서 설정들을 직접 주입하도록 손봤다.

수정된 MailConfig

application.properties에 있는 host, port 번호 등을 직접 넣어줬다.

@Configuration
public class MailConfig {

  @Value("${spring.mail.host}")
  private String host;

  @Value("${spring.mail.port}")
  private int port;

  @Value("${spring.mail.username}")
  private String username;

  @Value("${spring.mail.password}")
  private String password;

  @Bean
  public JavaMailSender javaMailSender() {
      JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
      mailSender.setHost(host);
      mailSender.setPort(port);
      mailSender.setUsername(username);
      mailSender.setPassword(password);
      return mailSender;
  }
}

하지만 이 역시 에러메세지를 출력했다.

에러메세지

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.mail.MailSendException: Failed messages: org.eclipse.angus.mail.smtp.SMTPSendFailedException: 530-5.7.0 Must issue a STARTTLS command first. ... ... ... org.springframework.mail.MailSendException: Failed messages: org.eclipse.angus.mail.smtp.SMTPSendFailedException: 530-5.7.0 Must issue a STARTTLS command first

에러메세지를 자세히 살펴보면 Must issue a STARTTLS command first를 요구하고 있다.
이것이 무엇일까?

STARTTLS

  • "Must issue a STARTTLS command first"라는 메시지는 이메일 클라이언트나 서버가 암호화된 통신을 위해 STARTTLS 명령을 사용해야 함을 나타내는 것입니다. STARTTLS는 안전한 통신을 위해 통신 채널을 암호화하는 명령입니다.
  • TLS(Transport Layer Security)는 네트워크 통신에서 데이터를 안전하게 전송하기 위한 프로토콜입니다. 이를 통해 데이터가 중간에 누출되거나 조작되지 않도록 보호할 수 있습니다. Gmail과 같은 이메일 서비스는 보안을 강화하기 위해 TLS를 사용하고 있습니다.

결론적으로 Gmail과 통신할 때, TLS를 사용하도록 설정해야 한다는 것이었다.
그럼 그것을 어떻게 해야하는 것인가..?

TLS를 사용하도록 설정 방법

  1. JavaMailSenderImpl 객체에서 속성(Properties)를 가져와서 SMTP 서버와의 통신 구성을 지정

  2. SMTP 서버와의 인증(authentication)을 사용하도록 설정
    (mail.smtp.auth : SMTP 서버에 인증을 요청할지 여부를 나타내는 속성 -> true로 설정하면 이메일을 보내기 전에 SMTP 서버에 로그인 인증을 시도)

  3. STARTTLS를 사용하여 SMTP 서버와의 통신을 암호화하도록 설정
    (mail.smtp.starttls.enable는 STARTTLS 명령을 사용할지 여부를 지정하는 속성 -> true로 설정하면 SMTP 서버와의 통신이 암호화)

최종 MailConfig

@Configuration
public class MailConfig {

  @Value("${spring.mail.host}")
  private String host;

  @Value("${spring.mail.port}")
  private int port;

  @Value("${spring.mail.username}")
  private String username;

  @Value("${spring.mail.password}")
  private String password;

  @Bean
  public JavaMailSender javaMailSender() {
    JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
    mailSender.setHost(host);
    mailSender.setPort(port);

    // STARTTLS를 명시적으로 추가
    Properties props = mailSender.getJavaMailProperties();
    props.put("mail.smtp.auth", true);
    props.put("mail.smtp.starttls.enable", true);

    mailSender.setUsername(username);
    mailSender.setPassword(password);

    return mailSender;
  }
}

이렇게 Config 설정을 마쳤더니 드디어 메일이 정상적으로 보내졌다!


이야.. 돌아보니 이걸 어떻게 찾아서 해결 했나 싶다.
에러메세지가 친절했던 덕분에, 모르더라도 잘 읽고 검색해보면서 해결 할 수 있었다.

에러와 친숙해지자!


관련 포스팅

Previous Post

Following Post

profile
I live in Seoul, Korea, Handsome

0개의 댓글