HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🍗
[New] 조규현팀
/
🏗️
Tech Store
/
✉️
Email
✉️

Email

담당자들
카테고리
주제
나의 블로그
완료율%
프로젝트
최종 프로젝트
상태
작성중
📥 간단 이메일 인증👀 추후 고려해볼만한 대안🔖 참고 사이트

📥 간단 이메일 인증

  1. 인증 정보 세팅
    1. (비추천) 보안 수준이 낮은 앱의 엑세스 허용하기
      1. [보안 수준이 낮은 앱의 엑세스] 해당 링크를 통해서 앱 허용을 해주셔야 합니다.
        notion image
        해당 설정을 사용하지 않으면 오류가 발생 됩니다. 😓
        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
         
        • 🤔 의문이 새롭게 계정을 생성해서 같은 곳으로 들어가면…
          • notion image
            사용할 수 없다고 나오게 됩니다. 😓 2차 인증을 해야 되는건가? 싶네요.→ 2차 인증을 해도 안됨
            notion image
            보안 수준이 낮은 앱 및 Google 계정
            계정을 안전하게 보호하기 위해 2022년 5월 30일 부터 ​​Google은 사용자 이름과 비밀번호만 사용하여 Google 계정에 로그인하도록 요청하는 서드 파티 앱 또는 기기의 사용을 더 이상 지원하지 않습니다. 중요: Google Workspace 또는 Google Cloud ID 고객에게는 이 기한이 적용되지 않습니다. 이러한 고객을 대상으로 한 시행일은 추후 Workspace 블로그에 공지될 예정입니다.
            보안 수준이 낮은 앱 및 Google 계정
            https://support.google.com/accounts/answer/6010255?hl=ko&visit_id=637950495068647686-2065665416&p=less-secure-apps&rd=1
            결국 로그인을 해서 메일을 보내는 구조다 보니.. 보안을 위해서 지원을 하지 않는 것 같습니다. 😱
    2. (추천) 2차 인증 설정
        • 계정 관리 → 보안 → 2단계 인증을 해줍니다.
          • notion image
        • 인증이 완료 되었다면, 같은 곳의 앱 비밀번호로 들어갑니다.
          • notion image
        • 앱 비밀번호를 생성해줍니다.
          • 앱 선택 → 기타
          • 기기 선택 → 기타(맞춤 이름)
          • 앱 이름 설정 후 생성 버튼을 클릭합니다.
          • notion image
            🐶  이제 생성된 기기용 앱 비밀번호를 사용하면 됩니다.
  1. 코드 작성
      • 라이브러리 추가
        • implementation 'org.springframework.boot:spring-boot-starter-mail'
        • MailSender 인터페이스
          • : 간단한 이메일을 보내기 위한 기본 기능을 제공하는 최상위 클래스
        • JavaMailSender 인터페이스
          • MailSender의 하위 인터페이스
          • MIME 메시지를 지원하며 대부분의 MimeMessge를 생성을 위해 MimeMessageHelper 클래스와 함께 사용
          • 이 인터페이스와 함께 MimeMessagePreparator 메커니즘을 사용하는 것이 좋다.
        • JavaMailSenderImpl 클래스
          • : JavaMailSenderMimeMessage 및 SimpleMailMessage 인터페이스 의 구현을 제공합니다.
        • SimpleMailMessage 클래스
          • : 보낸 사람, 받는 사람, 참조, 제목 및 텍스트 필드를 포함하는 간단한 메일 메시지를 만드는 데 사용
        • MimeMessagePreparator 인터페이스
          • : MIME 메시지 준비를 위한 콜백 인터페이스를 제공합니다.
        • MimeMessageHelper 클래스
          • MIME 메시지 생성을 위한 도우미 클래스입니다. 
          • HTML 레이아웃의 이미지, 일반적인 메일 첨부 파일 및 텍스트 콘텐츠에 대한 지원을 제공합니다.
      • 설정 파일 작성
        • 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
        • connectiontimeout, timout, writetimeout : 무한 대기 상태를 피하기 위한 시간 설정
      • 이메일 서비스 생성 및 사용
          1. 이메일 서비스 생성
            1. @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); } }
              • email : 사용되는 이메일을 등록
              • authToken : UUID를 사용
          1. 사용
            1. 이제 메일을 보내게 되면 다음과 같이 이메일이 발송 됩니다.
              notion image
              해당 링크로 요청을 통해서 인증 처리를 하게 되는 것이죠.
               
      • 끗.
       

👀 추후 고려해볼만한 대안

  • 두 번째 방법 - AWS SES(Simple Email Service) 사용 → 단점으로는 하나의 관리 대상인 리소스가 더 생긴다는 점이 있습니다.

🔖 참고 사이트

www.baeldung.com
https://www.baeldung.com/spring-email
[SpringBoot] 이메일 전송 ( JavaMailSender, MimeMessageHelper )
이번 글에서는 MailSender 인터페이스를 상속받은 JavaMailSender 를 사용하여 이메일 전송 시스템을 구현해보도록 하겠습니다. 개발환경 1. 준비 작업 build.gradle dependencies implementation 'org.springframework.boot:spring-boot-starter-mail''org.springframework.boot:spring-boot-starter-thymeleaf''org.springframework.boot:spring-boot-starter-web''org.projectlombok:lombok''org.projectlombok:lombok''junit-vintage-engine'implementation implementation compileOnly annotationProcessor testImplementation('org.springframework.boot:spring-boot-starter-test') exclude group: 'org.junit.vintage', module: } 이메일 발송을 위해 spring-boot-starter-mail 의존성을 추가합니다. 프로젝트 구조 2. Gmail SMTP Server 설정 이 글에서는 구글 계정만 있으면 무료로 발송할 수 있는 Gmail SMTP Server 를 이용할 것입니다.
[SpringBoot] 이메일 전송 ( JavaMailSender, MimeMessageHelper )
https://victorydntmd.tistory.com/342
[SpringBoot] 이메일 전송 ( JavaMailSender, MimeMessageHelper )
workshop-6349.tistory.com
https://workshop-6349.tistory.com/entry/%EA%B4%B4%EB%B0%9C%EA%B0%9C%EB%B0%9C-REST-API-%EC%9D%B4%EB%A9%94%EC%9D%BC-%EC%9D%B8%EC%A6%9D?category=1007169
[서버개발캠프] 인증 서버 - 이메일 인증 회원가입
이메일 인증을 기반으로 회원가입 로직을 작성했다. 로직은 다음과 같다. 1. 사용자가 이메일과 비밀번호 등 회원정보를 입력한 후, 회원가입 요청을 보낸다.2. 서버에서는 사용자의 이메일로 인증메일을 전송하고, 사용자가 입력한 정보를 Redis에 임시저장한다.3. 사용자가 전송된 메일의 링크를 통해 인증확인 요청을 보낸다.4. 서버에서는 인증확인 후, Redis에 저장 된 회원 정보를 DB에 저장하며 회원가입을 마친다.
[서버개발캠프] 인증 서버 - 이메일 인증 회원가입
https://yunb2.tistory.com/4
[서버개발캠프] 인증 서버 - 이메일 인증 회원가입