📥 간단 이메일 인증
- 인증 정보 세팅
- (비추천) 보안 수준이 낮은 앱의 엑세스 허용하기
- 🤔 의문이 새롭게 계정을 생성해서 같은 곳으로 들어가면…
- (추천) 2차 인증 설정
- 계정 관리 → 보안 → 2단계 인증을 해줍니다.
- 인증이 완료 되었다면, 같은 곳의 앱 비밀번호로 들어갑니다.
- 앱 비밀번호를 생성해줍니다.
- 앱 선택 → 기타
- 기기 선택 → 기타(맞춤 이름)
- 앱 이름 설정 후 생성 버튼을 클릭합니다.
[보안 수준이 낮은 앱의 엑세스] 해당 링크를 통해서 앱 허용을 해주셔야 합니다.

해당 설정을 사용하지 않으면 오류가 발생 됩니다. 😓
Authentication failed; … Username and Password not accepted.
오류 로그 전문
2022-08-02 12:09:13.900 ERROR 11295 --- [ task-1] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: public void com.midas.email.service.EmailService.send(java.lang.String,java.lang.String) org.springframework.mail.MailAuthenticationException: Authentication failed; nested exception is javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at 535 5.7.8 https://support.google.com/mail/?p=BadCredentials u5-20020a17090a4bc500b001ef7c7564fdsm12374825pjl.21 - gsmtp at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:440) ~[spring-context-support-5.3.22.jar:5.3.22] at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:323) ~[spring-context-support-5.3.22.jar:5.3.22] at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:312) ~[spring-context-support-5.3.22.jar:5.3.22] at com.midas.email.service.EmailService.send(EmailService.java:24) ~[classes/:na] at com.midas.email.service.EmailService$$FastClassBySpringCGLIB$$c19cfe05.invoke(<generated>) ~[classes/:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.22.jar:5.3.22] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.22.jar:5.3.22] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.22.jar:5.3.22] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.22.jar:5.3.22] at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.3.22.jar:5.3.22] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na] Caused by: javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at 535 5.7.8 https://support.google.com/mail/?p=BadCredentials u5-20020a17090a4bc500b001ef7c7564fdsm12374825pjl.21 - gsmtp at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:947) ~[jakarta.mail-1.6.7.jar:1.6.7] at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:858) ~[jakarta.mail-1.6.7.jar:1.6.7] at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:762) ~[jakarta.mail-1.6.7.jar:1.6.7] at javax.mail.Service.connect(Service.java:342) ~[jakarta.mail-1.6.7.jar:1.6.7] at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:518) ~[spring-context-support-5.3.22.jar:5.3.22] at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:437) ~[spring-context-support-5.3.22.jar:5.3.22] ... 13 common frames omitted

사용할 수 없다고 나오게 됩니다. 😓 2차 인증을 해야 되는건가? 싶네요.→ 2차 인증을 해도 안됨

결국 로그인을 해서 메일을 보내는 구조다 보니.. 보안을 위해서 지원을 하지 않는 것 같습니다. 😱



🐶 이제 생성된 기기용 앱 비밀번호를 사용하면 됩니다.
- 코드 작성
- 라이브러리 추가
- MailSender 인터페이스
- JavaMailSender 인터페이스
- MailSender의 하위 인터페이스
- MIME 메시지를 지원하며 대부분의 MimeMessge를 생성을 위해 MimeMessageHelper 클래스와 함께 사용
- 이 인터페이스와 함께 MimeMessagePreparator 메커니즘을 사용하는 것이 좋다.
- JavaMailSenderImpl 클래스
- SimpleMailMessage 클래스
- MimeMessagePreparator 인터페이스
- MimeMessageHelper 클래스
- MIME 메시지 생성을 위한 도우미 클래스입니다.
- HTML 레이아웃의 이미지, 일반적인 메일 첨부 파일 및 텍스트 콘텐츠에 대한 지원을 제공합니다.
- 설정 파일 작성
connectiontimeout
,timout
,writetimeout
: 무한 대기 상태를 피하기 위한 시간 설정- 이메일 서비스 생성 및 사용
- 이메일 서비스 생성
- email : 사용되는 이메일을 등록
- authToken : UUID를 사용
- 사용
- 끗.
implementation 'org.springframework.boot:spring-boot-starter-mail'
: 간단한 이메일을 보내기 위한 기본 기능을 제공하는 최상위 클래스
: JavaMailSenderMimeMessage 및 SimpleMailMessage 인터페이스 의 구현을 제공합니다.
: 보낸 사람, 받는 사람, 참조, 제목 및 텍스트 필드를 포함하는 간단한 메일 메시지를 만드는 데 사용
: MIME 메시지 준비를 위한 콜백 인터페이스를 제공합니다.
spring: application: name: spring-email mail: host: smtp.gmail.com port: 587 username: ${SMTP_EMAIL} password: ${SMTP_PASSWORD} # 2차 인증 방법이면 앱 비밀번호! properties: mail: smtp: starttls: enable: true required: true auth: true connectiontimeout: 5000 timout: 5000 writetimeout: 5000
@EnableAsync @RequiredArgsConstructor @Service public class EmailService { private final JavaMailSender javaMailSender; @Async public void send(String email, String authToken) { SimpleMailMessage smm = new SimpleMailMessage(); smm.setTo(email); smm.setSubject("회원가입 이메일 인증"); smm.setText("http://localhost:8080/api/users/confirm-email?email=" + email + "&authToken=" + authToken); javaMailSender.send(smm); } }
이제 메일을 보내게 되면 다음과 같이 이메일이 발송 됩니다.

해당 링크로 요청을 통해서 인증 처리를 하게 되는 것이죠.
👀 추후 고려해볼만한 대안
- 두 번째 방법 - AWS SES(Simple Email Service) 사용 → 단점으로는 하나의 관리 대상인 리소스가 더 생긴다는 점이 있습니다.