휴대폰 번호 중복 가입 가능

This commit is contained in:
Rinjae
2025-10-01 20:32:44 +09:00
parent aae49583dd
commit 3ad3bd087e
4 changed files with 82 additions and 35 deletions
@@ -37,9 +37,15 @@ public class AuthNumberServiceImpl implements AuthNumberService {
this.messageSender = messageSender;
}
/**
* 이메일 인증도 가능하도록 개선
* @param recipientKey
* @param msgType
*/
@Override
@Transactional(noRollbackFor = AuthNumberException.class)
public void sendRequestAuthNumber(String recipientKey, String msgType) {
// TODO: 이메일 인증도 가능하도록 개선
logger.info("Sending auth number to: {} via {}", recipientKey, msgType);
validateResendTime(recipientKey);
@@ -2,6 +2,7 @@ package com.eactive.apim.portal.apps.user.controller;
import com.eactive.apim.portal.apps.user.dto.ValidationResponse;
import com.eactive.apim.portal.apps.user.facade.AuthFacade;
import com.eactive.apim.portal.apps.user.validator.EmailValidator;
import com.eactive.apim.portal.common.validator.CellPhoneValidator;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -20,12 +21,16 @@ public class AuthController {
private final AuthFacade authFacade;
private final CellPhoneValidator cellPhoneValidator;
private final EmailValidator emailValidator;
public AuthController(AuthFacade authFacade, CellPhoneValidator cellPhoneValidator) {
public AuthController(AuthFacade authFacade, CellPhoneValidator cellPhoneValidator, EmailValidator emailValidator) {
this.authFacade = authFacade;
this.cellPhoneValidator = cellPhoneValidator;
this.emailValidator = emailValidator;
}
@PostMapping("/request_auth_number")
public ValidationResponse requestAuthNumber(
@RequestParam(required = false) String mobileNumber,
@@ -89,6 +94,33 @@ public class AuthController {
return response;
}
@PostMapping("/request-otp-email")
public ValidationResponse requestOtpForEmail(
@RequestParam(required = false) String email,
HttpSession session) {
// TODO: 이메일 주소 인증 기능 개선
ValidationResponse response = new ValidationResponse();
email = email.trim();
if (!emailValidator.isValidEmail(email)) {
response.setValid(false);
response.setMessage("유효하지 않은 이메일 형식입니다.");
return response;
}
response = authFacade.requestAuth(email, "EMAIL");
if (response.isValid()) {
// session.setAttribute("mobileNumber", sanitizedMobile);
}
return response;
}
private void clearAuthSessionData(HttpSession session) {
session.removeAttribute("mobileNumber");
session.removeAttribute("isVerified");
@@ -15,6 +15,14 @@ public class AuthFacadeImpl implements AuthFacade {
private final AuthNumberService authNumberService;
private static final Logger log = LoggerFactory.getLogger(AuthFacadeImpl.class);
/**
* 인증 요청
* 25.10.01 - 이메일 인증도 가능하도록 개선
* @param recipientKey
* @param msgType "SMS", "EMAIL" (대소문자 구분 안함)
* @return
*/
@Override
public ValidationResponse requestAuth(String recipientKey, String msgType) {
ValidationResponse response = new ValidationResponse();
@@ -26,7 +34,7 @@ public class AuthFacadeImpl implements AuthFacade {
return response;
}
if (!"SMS".equalsIgnoreCase(msgType)) {
if (!"SMS".equalsIgnoreCase(msgType) && !"EMAIL".equalsIgnoreCase(msgType)) {
response.setValid(false);
response.setMessage("유효하지 않은 인증 방식입니다.");
return response;
@@ -2,6 +2,7 @@ package com.eactive.apim.portal.apps.user.facade;
import com.eactive.apim.portal.agreements.entity.AgreementType;
import com.eactive.apim.portal.apps.agreements.service.AgreementsFacade;
import com.eactive.apim.portal.apps.auth.service.AuthNumberGenerator;
import com.eactive.apim.portal.apps.user.dto.PortalUserRegistrationDTO;
import com.eactive.apim.portal.apps.user.dto.UserAgreementDTO;
import com.eactive.apim.portal.apps.user.dto.ValidationResponse;
@@ -10,7 +11,6 @@ import com.eactive.apim.portal.apps.user.service.PortalUserService;
import com.eactive.apim.portal.apps.user.service.UserRegistrationValidationService;
import com.eactive.apim.portal.apps.user.validator.AgreementValidator;
import com.eactive.apim.portal.apps.user.validator.PasswordValidator;
import com.eactive.apim.portal.common.exception.SystemException;
import com.eactive.apim.portal.common.util.EncryptionUtil;
import com.eactive.apim.portal.invitation.entity.UserInvitation;
import com.eactive.apim.portal.invitation.entity.UserInvitationEnums;
@@ -20,19 +20,7 @@ import com.eactive.apim.portal.portaluser.event.UserEmailActivationEvent;
import com.eactive.apim.portal.portaluser.repository.PortalUserRepository;
import com.eactive.apim.portal.template.service.MessageHandlerService;
import com.eactive.apim.portal.template.service.MessageRecipient;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Optional;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.apache.xerces.impl.dv.util.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
@@ -41,6 +29,11 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class UserRegisterFacadeImpl implements UserRegisterFacade {
@@ -58,6 +51,8 @@ public class UserRegisterFacadeImpl implements UserRegisterFacade {
private final AgreementValidator agreementValidator;
private final MessageHandlerService messageHandlerService;
private final EncryptionUtil encryptionUtil;
private final AuthNumberGenerator authNumberGenerator;
@Override
public ValidationResponse handleCheckId(String loginId, String registrationType) {
@@ -110,7 +105,7 @@ public class UserRegisterFacadeImpl implements UserRegisterFacade {
ValidationResponse response = new ValidationResponse();
Optional<PortalUser> user = portalUserRepository.findPortalUserByEmailAddr(loginId);
if (user != null && passwordEncoder.matches(confirmPassword, user.get().getPasswordHash())) {
if (user.isPresent() && passwordEncoder.matches(confirmPassword, user.get().getPasswordHash())) {
response.setValid(true);
response.setMessage("비밀번호가 확인되었습니다.");
} else {
@@ -137,20 +132,22 @@ public class UserRegisterFacadeImpl implements UserRegisterFacade {
return new ValidationResponse(false,"입력값을 확인해 주세요.");
}
PortalUser existingUser = portalUserRepository.findByUserNameAndMobileNumber(registrationDTO.getUserName(), registrationDTO.getMobileNumber());
// 25.10.01 - 휴대폰 번호 중복이여도 가입 가능
// PortalUser existingUser = portalUserRepository.findByUserNameAndMobileNumber(registrationDTO.getUserName(), registrationDTO.getMobileNumber());
//
// if(existingUser != null) {
// return new ValidationResponse(false, "가입된 계정이 이미 존재합니다.");
// }
if(existingUser != null) {
return new ValidationResponse(false, "가입된 계정이 이미 존재합니다.");
// 3. 사용자 등록 ("personal" 등록 유형으로 가정)
PortalUser newUser = portalUserService.registerActiveUser(registrationDTO, "personal");
if (newUser == null) {
return new ValidationResponse(false,"사용자 등록에 실패했습니다.");
}
// 3. 사용자 등록 ("personal" 등록 유형으로 가정)
PortalUser newUser = portalUserService.registerActiveUser(registrationDTO, "personal");
if (newUser == null) {
return new ValidationResponse(false,"사용자 등록에 실패했습니다.");
}
agreementsFacade.saveUserAgreements(newUser.getId(), AgreementType.PRIVACY_COLLECT_IND);
sendEmailActivation(newUser);
return new ValidationResponse(true,"회원가입이 완료되었습니다.");
agreementsFacade.saveUserAgreements(newUser.getId(), AgreementType.PRIVACY_COLLECT_IND);
sendEmailActivation(newUser);
return new ValidationResponse(true,"회원가입이 완료되었습니다.");
}
@Override
@@ -217,16 +214,20 @@ public class UserRegisterFacadeImpl implements UserRegisterFacade {
recipient.setUserId(registeredUser.getEmailAddr());
recipient.setPhone(registeredUser.getMobileNumber());
// 25.10.01 - 이메일 링크 방식으로 접근 불가이기에 SMS 인증방식과 동일하게 대체
HashMap<String, Object> params = new HashMap<>();
String tokenValue = registeredUser.getCreatedDate().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")) + ":" + registeredUser.getId();
try {
String encToken = encryptionUtil.encrypt(tokenValue);
params.put("token", Base64.encode(encToken.getBytes(StandardCharsets.UTF_8)));
messageHandlerService.publishEvent(UserEmailActivationEvent.KEY, recipient, params);
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
throw new SystemException("암호화 모듈 오류");
}
String tokenValue = String.valueOf(authNumberGenerator.generateAuthNumber());
// String tokenValue = registeredUser.getCreatedDate().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")) + ":" + registeredUser.getId();
params.put("token", tokenValue);
messageHandlerService.publishEvent(UserEmailActivationEvent.KEY, recipient, params);
// try {
// String encToken = encryptionUtil.encrypt(tokenValue);
// params.put("token", Base64.encode(encToken.getBytes(StandardCharsets.UTF_8)));
// messageHandlerService.publishEvent(UserEmailActivationEvent.KEY, recipient, params);
// } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
// throw new SystemException("암호화 모듈 오류");
// }
}
@Override