프로젝트

[개인] 이메일 인증 구현(Naver) #2 | 뜨거

나는시화 2024. 2. 7. 15:09

스프링 부트 이메일 인증 구현 #1

인증번호 요청 확인


EmailAuthChkRequestDto, EmailAuthChkResponseDto 작성 

  • email과 인증 번호를 받아와줌 
// RequestDto
@Getter @Setter
@NoArgsConstructor
public class EmailAuthChkRequestDto {
    @NotBlank
    private String email;
    @NotBlank
    private String emailAuthValue;
}

 

  • 이메일이 유효하지 않은 경우 400
  • 이미 가입된 이메일인 경우 400
  • 이메일 인증이 성공적으로 완료됐을 경우 200
// ResponseDto

@Getter
public class EmailAuthChkResponseDto extends ResponseDto {
    private String email;
    public EmailAuthChkResponseDto(String email) {
        super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
        this.email = email;
    }
    public static ResponseEntity<EmailAuthChkResponseDto> success(String email){
        EmailAuthChkResponseDto responseBody = new EmailAuthChkResponseDto(email);
        return ResponseEntity.status(HttpStatus.OK).body(responseBody);
    }
    public static ResponseEntity<ResponseDto> validationFailEmail(){ // 유효하지 않은 이메일
        ResponseDto responseBody = new ResponseDto(ResponseCode.VALIDATION_FAIL, ResponseMessage.VALIDATION_FAIL);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseBody);
    }
    public static ResponseEntity<ResponseDto> duplicateEmail(){ // 이메일 중복
        ResponseDto responseBody = new ResponseDto(ResponseCode.DUPLICATE_EMAIL, ResponseMessage.DUPLICATE_EMAIL);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseBody);
    }
    
}

이메일 인증 확인 컨트롤러

package com.eemgu.usedproducts.web.controller;

import com.eemgu.usedproducts.domain.dto.request.auth.EmailAuthChkRequestDto;
import com.eemgu.usedproducts.domain.dto.request.auth.EmailAuthRequestDto;
import com.eemgu.usedproducts.domain.dto.request.auth.SignInRequestDto;
import com.eemgu.usedproducts.domain.dto.request.auth.SignUpRequestDto;
import com.eemgu.usedproducts.domain.dto.response.auth.*;
import com.eemgu.usedproducts.domain.service.AuthService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/auth")
@Slf4j
public class AuthController {

    @PostMapping("/sign-up/email-auth") // 이메일 인증 요청
    public ResponseEntity<? super EmailAuthResponseDto> signUpEmailAuth(
            @RequestBody EmailAuthRequestDto dto){
        ResponseEntity<? super EmailAuthResponseDto> response = authService.emailAuth(dto);
        return response;
    }
    @PostMapping("/sign-up/email-auth-chk") // 이메일 인증 확인
    public ResponseEntity<? super EmailAuthChkResponseDto> signUpEmailAuthChk(
            @RequestBody EmailAuthChkRequestDto dto){
        ResponseEntity<? super EmailAuthChkResponseDto> response = authService.emailAuthChk(dto);
        return response;
    }

}

이메일 인증 확인 로직

@Service
@RequiredArgsConstructor
public class AuthServiceImplement implements AuthService {

    private final AuthNumberService authNumberService;
    private final UserEntityService userEntityService;
    private final EmailProvider emailProvider;
    private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    private final JwtProvider jwtProvider;

    @Override // 이메일 인증 요청
    public ResponseEntity<? super EmailAuthResponseDto> emailAuth(EmailAuthRequestDto dto) {
     ... 생략
	}

    @Override // 이메일 인증 확인
    public ResponseEntity<? super EmailAuthChkResponseDto> emailAuthChk(EmailAuthChkRequestDto dto) {
        String email = dto.getEmail();
        String dtoGetAuthNumber = dto.getEmailAuthValue();
        try{
            Optional<UserEntity> userOptional = userEntityService.findByEmail(email);
            if(userOptional.isPresent()) return EmailAuthChkResponseDto.duplicateEmail(); // 중복 이메일
            Optional<AuthNumber> authNumberOptional = authNumberService.findByEmailPhone(email);
            if(authNumberOptional.isEmpty()) return EmailAuthChkResponseDto.validationFailEmail(); // 유효하지 않은 이메일인 경우

            AuthNumber authNumber = authNumberOptional.get();
            if(!authNumber.getAuthNumber().equals(dtoGetAuthNumber))
                return EmailAuthChkResponseDto.validationFailEmail(); // 인증 번호가 틀렸을 경우

            authNumberService.deleteByEmailPhone(email);
        } catch (Exception e){
            e.printStackTrace();
            return EmailAuthChkResponseDto.databaseError();
        }
        return EmailAuthChkResponseDto.success(email);
    }




}

인증 확인

  • email도 같이 반환해주는 이유는 back에서 보내준 email과 클라이언트의 email이 다른 경우 다시 인증하라는 메세지를 띄워주기 위함.(인증 확인을 한 후에 email을 변경하는 경우를 대비)