BE/Spring Boot

[Spring Boot] SMTP로 구글 이메일 인증 기능 구현 (회원가입)

셰욘 2025. 2. 19. 21:19
728x90

이메일 인증 기능 구현

이메일(Gmail) 인증을 통해 엔티티의 enabled 속성을 true로 바꿔줄 것이다.

 

Gmail 설정, 앱 비밀번호 생성

Gmail 들어가서 오른쪽 상단 톱니바퀴 - 모든 설정 보기

 

 

설정에 전달 및 POP/IMAP

-> IMAP 사용, 자동 삭제 사용으로 바꿔준 후 변경사항 저장

 

 

 

구글 계정 - 앱 비밀번호

앱 이름 아무거나 입력한다. 

 

 

앱 이름을 입력 후 만들기를 누르면 앱 비밀번호가 나온다.

앱 비밀번호 복사해두기 !

 

 

 


프로젝트에서 이메일 인증 기능 구현

mail 라이브러리 추가

implementation 'org.springframework.boot:spring-boot-starter-mail'

 

 

application.yml에 설정

application.yml에 메일 설정을 해준다. 

mail.username은 사용자에게 메일을 보낼 이메일(앱 비밀번호를 만든 이메일)을 작성하고,

mail.password는 위에서 만든 구글 앱 비밀번호를 넣으면 된다. 

spring:
  mail:
    # 구글 메일 서버 주소 (send mail test protocol)
    host: smtp.gmail.com
    # 구글 메일 서버 포트번호
    port: 587
    # 사용자에게 메일을 보낼 이메일 작성
    username: ${MAIL_ADDR}
    # 구글 개인정보 설정에서 발급 받은 비밀번호
    password: ${MAIL_PASSWORD}
    properties:
      mail:
        smtp:
          starttls:
            enable: true
            required: true
          auth: true
          # 5초 안에 메일이 가지 않으면 처리 x
          timeout: 5000

 

 

 

서비스에 이메일을 보내는 코드 작성 ( JavaMailSender )

서비스에 이메일을 보내는 코드를 작성한다.

 

setSubject : 메일 제목

setText : 메일 내용

 

@Service
@RequiredArgsConstructor
public class UserService implements UserDetailsService {
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final JavaMailSender mailSender;

    public void sendEmail(String email) {
        String uuid = UUID.randomUUID().toString();
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(email);
        message.setSubject("[환영] 웰컴");
        message.setText(
                String.format(
                """
                    "http://localhost:8080/user/verify?uuid=%s"
                    이메일 인증하기
                """
                , uuid)
        );

        mailSender.send(message);
    }
    public UserDto.SignupResponse signup(UserDto.SignupRequest dto) {

        sendEmail(dto.getEmail());
        User user = userRepository.save(dto.toEntity(passwordEncoder.encode(dto.getPassword())));

        return UserDto.SignupResponse.from(user);
    }
}

 

 

테스트 (회원가입 해보기)

메일을 받을 이메일로 회원가입을 한다.

 

 

회원가입 요청을 보내면 메일이 오는 걸 확인할 수 있다!! 

 

 

 

 


uuid로 이메일 인증 정보를 DB에 저장 후 enabled 처리

EmailVerify 엔티티를 만들어서 인증 정보를 담을 테이블을 생성하고,

회원가입 시 생성한 uuid로 이메일 인증 정보를 저장한 후

해당 uuid로 verify 요청이 오면 회원의 enabled 값을 true로 수정해줄 것이다.

 

엔티티 - EmailVerify

연관 관계 매핑으로 User 엔티티와 연결해준다.

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Getter
public class EmailVerify {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long idx;
    private String uuid;

    @ManyToOne
    @JoinColumn(name="user_idx")
    private User user;

}

 


User 엔티티에 verify 메소드 추가

회원의 enabled 를 true로 변경해주는 메소드를 추가한다.

public void userVerify() {
  this.enabled = true;
}

 


레파지토리 - EmailVerifyRepository

uuid로 조회할 것이기 때문에 findByUuid 메소드를 추가해준다.

public interface EmailVerifyRepository extends JpaRepository<EmailVerify, Long> {
    Optional<EmailVerify> findByUuid(String uuid);
}

 


 

서비스 - UserService

회원가입 시 uuid를 생성해서 이메일 인증 정보에 user와 함께 저장해준다.

저장해준 후 생성한 uuid를 담은 url를 메일로 보내고,

메일에서 해당 링크를 클릭하면 GET 요청 /user/verify 으로 넘어오게 된다.

 

 

sendEmail 메소드

  • 매개변수로 uuid를 넘겨받아 URL에 담아준다.
@Service
@RequiredArgsConstructor
public class UserService implements UserDetailsService {
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final JavaMailSender mailSender;
    private final EmailVerifyRepository emailVerifyRepository;

    public void sendEmail(String uuid, String email) {

        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(email);
        message.setSubject("[환영] 웰컴");
        message.setText(
                String.format("""
                        "http://localhost:8080/user/verify?uuid=%s"
                        이메일 인증하기
                        """, uuid)
        );

        mailSender.send(message);
    }
	
    // ...

}

 

 

signup 메소드

  • 회원가입 시 uuid를 생성해서 이메일 인증 정보에 user와 함께 저장해준다.
  • 저장해준 후 생성한 uuid를 담은 URL을 내용에 넣어서 이메일을 전송한다.
public UserDto.SignupResponse signup(UserDto.SignupRequest dto) {
    String uuid = UUID.randomUUID().toString();

    User user = userRepository.save(dto.toEntity(passwordEncoder.encode(dto.getPassword())));

    // 이메일 인증 정보 저장
    emailVerifyRepository.save(EmailVerify.builder()
            .user(user)
            .uuid(uuid)
            .build());
    // 이메일 전송
    sendEmail(uuid, dto.getEmail());

    return UserDto.SignupResponse.from(user);
}

 

 

verify 메소드

  • 레파지토리를 통해 findByUuid 메소드를 실행해서 uuid에 해당하는 회원을 가져온다.
    • 데이터가 없으면 자동으로 예외 처리해준다. (orElseThrow)
  • userVerify 메소드를 호출해서 해당 회원의 enabled 값을 true로 바꿔준다.
  • 바꿔준 후 해당 회원의 데이터를 변경시켜준다. (save하면 자동으로 바뀐 값이 업데이트되어 저장된다.)
public void verify(String uuid) {
    EmailVerify emailVerify = emailVerifyRepository.findByUuid(uuid).orElseThrow();

    User user = emailVerify.getUser();
    user.userVerify();

    userRepository.save(user);
}

 


컨트롤러 - UserController

이메일을 받은 사용자가 URL을 누르면 해당 요청으로 오게 된다.

verify 메소드를 호출해서 회원 정보 변경을 처리해준다.

 

SecurityConfig에서 해당 URL을 permitAll 처리해줘야 한다.

@GetMapping("/verify")
public void verify(String uuid) {
    userService.verify(uuid);
}

 

 

 

 

 

이메일의 링크를 누른 사용자는 enabled 가 1로 바뀐다.

728x90