클라이언트측에서 즉시 알림처리
이메일 중복 확인 API를 새로 구현해서
클라이언트에서 서버로 이메일 중복 확인 요청
- 서버에서는 이메일 중복 여부를 클라이언트에게 반환
- 중복된 이메일인 경우 기존의 흐름대로 알림처리
- 중복된 이메일이 아닌 경우 즉시 알림을 출력하고 인증 번호를 전송하는 요청을 보내도록 설계
서버에서 즉시 알림을 처리
이메일 중복 확인 API를 새로 구현할 필요없이 기존의 로직을 사용하면서
클라이언트에서 인증번호 전송 버튼을 클릭하면
- 서버에서는 이메일 중복 여부를 확인
- 중복된 이메일인 경우 기존의 흐름대로 알림처리
- 중복된 이메일이 아닌 경우 클라이언트에게 인증번호를 전송함을 알리고 인증번호 전송 작업은 별도 비동기 작업으로 처리하도록 설계
첫 번째 방법은
- 서버에 요청을 두 번 보내야함.
- 많은 사용자가 동시에 인증번호를 요청하는 경우 서버에 부담이 될 수 있음
- 클라이언트측 코드를 수정해야 함.
어쨋든 나는 백엔드 개발자가 목표이니까 백엔드에서 로직을 처리하는 두 번째 방법을 선택해서 구현해보자.
- 클라이언트에서 인증번호 전송 요청을 보낸다.
- 서버에서는 먼저 이메일 중복 확인(checkEmailDuplication)을 수행한다.
/**
* 이메일 인증번호 전송
*/
@Operation(summary = "이메일 인증번호 전송", description = "사용자의 이메일 주소를 입력받아 인증번호를 전송합니다.")
@PostMapping
public ResponseEntity<String> sendVerificationCode(
@Parameter(
description = "이메일 주소를 입력하세요",
required = true
)
@RequestParam String email
) {
return ResponseEntity.ok(emailVerificationService.checkEmailDuplication(email));
};
- 중복된 이메일이 없는 경우 비동기로 이메일 인증번호 전송을 수행한다.
- 인증번호 전송 과정이 비동기로 처리되는 동안 checkEmailDuplication() 메서드에서 "인증번호가 전송되었습니다."과 함께 200응답을 반환한다.
/**
* 이메일 중복 체크
*/
public String checkEmailDuplication(String email) {
validateEmailFormat(email);
if (userService.findByEmail(email) != null) {
throw new ConflictException("이미 사용 중인 이메일입니다.");
}
// 인증 번호를 전송하는 과정을 비동기로 수행
CompletableFuture.runAsync(() -> sendVerificationCode(email));
return VERIFICATION_CODE + "가 전송되었습니다.";
}
/**
* 이메일 인증번호 전송
*/
private void sendVerificationCode(String email) {
// 1. 기존에 저장된 인증번호가 있는 경우 삭제
EmailVerification emailVerification = emailVerificationDao.selectByEmail(email);
if (emailVerification != null) {
emailVerificationDao.deleteByEmail(email);
}
// 2. 새로운 인증번호 생성 및 저장
String newVerificationCode = generateVerificationCode();
emailVerification = new EmailVerification();
emailVerification.setEmail(email);
emailVerification.setVerificationCode(newVerificationCode);
emailVerification.setExpiresAt(LocalDateTime.now().plusMinutes(3));
emailVerificationDao.insertEmailVerification(emailVerification);
// 3. 이메일 전송
sendEmail(email, newVerificationCode);
}
- 클라이언트는 200응답을 확인하고 인증번호 전송 과정이 마무리 되는 것과는 상관없이 "인증번호가 전송되었습니다." 알림을 출력한다.
/**
* 이메일 인증번호 전송
*/
const sendVerificationCode = function (email) {
return axios.post(`${REST_API}`, null,
{ params: { email }
})
.then((response) => {
alert('인증번호가 전송되었습니다.')
})
.catch((error) => {
switch (error.response.status) {
case 409:
alert(error.response.data.message)
break;
default:
alert('인증번호 전송 실패')
}
})
}
문제 해결
중복된 이메일인 경우 중복 알림을 제대로 출력하고
중복된 이메일이 아닌 경우 알림을 즉시 출력하고 인증번호도 제대로 전송한다.
문제 해결의 키 포인트는 인증번호 전송 과정을 비동기로 수행하는 것이었다.
'고민거리' 카테고리의 다른 글
| [최적화] 게시글 (0) | 2025.04.05 |
|---|---|
| [고민거리] 작성자 : 댓글 연관 관계 매핑 (0) | 2025.03.06 |
| [리팩토링] 이메일 인증번호 전송 사용자 경험 개선 - 1 (0) | 2025.01.10 |
| [디버깅] 이메일 중복 오류 (0) | 2025.01.09 |
| 로직의 위치 (0) | 2025.01.06 |