From c42a278c8ec6f5041c25128f74556de1a918a4e6 Mon Sep 17 00:00:00 2001 From: Rinjae Date: Fri, 7 Aug 2026 09:20:39 +0900 Subject: [PATCH] =?UTF-8?q?=EC=88=98=EC=8B=A0=EC=9E=90=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=A7=80=EC=A0=95=20=EC=9D=B8=EC=A6=9D=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=B0=9C=EC=86=A1=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80:=20-=20%USER=5FNAME%=20=EC=A7=80=EC=9B=90=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20createMessageRecipient=20=EC=88=98=EC=A0=95=20-=20G?= =?UTF-8?q?UEST=5FUSER=5FNAME=20=EC=83=81=EC=88=98=20=EB=B0=8F=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EA=B8=B0=EB=B3=B8=EA=B0=92=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/auth/service/AuthNumberService.java | 12 ++++++++++ .../auth/service/AuthNumberServiceImpl.java | 22 ++++++++++++++++--- .../apps/user/facade/AuthFacadeImpl.java | 8 ++++++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/eactive/apim/portal/apps/auth/service/AuthNumberService.java b/src/main/java/com/eactive/apim/portal/apps/auth/service/AuthNumberService.java index a142517..b747af2 100644 --- a/src/main/java/com/eactive/apim/portal/apps/auth/service/AuthNumberService.java +++ b/src/main/java/com/eactive/apim/portal/apps/auth/service/AuthNumberService.java @@ -4,11 +4,23 @@ public interface AuthNumberService { String sendRequestAuthNumber(String recipientKey, String msgType); + /** + * 기본 TTL 로 발송하되 수신자 이름을 지정한다. 세 번째 인자가 int 인 오버로드(TTL 지정)와 혼동하지 말 것. + */ + String sendRequestAuthNumber(String recipientKey, String msgType, String username); + /** * 인증번호를 지정한 유효시간(초)으로 발송한다. 로그인/step-up 2FA 는 회원가입 기본 TTL 과 * 다른 값을 쓸 수 있으므로 호출부에서 TTL 을 지정한다. */ String sendRequestAuthNumber(String recipientKey, String msgType, int ttlSeconds); + /** + * 수신자 이름을 지정해 인증번호를 발송한다. 메시지 템플릿의 %USER_NAME% 치환에 사용되며, + * 회원가입·아이디/비밀번호 찾기처럼 사용자 이름을 알 수 없는 흐름은 "guest" 를 넘긴다. + * username 이 비어 있으면 %USER_NAME% 은 치환되지 않고 원문이 그대로 남는다. + */ + String sendRequestAuthNumber(String recipientKey, String msgType, int ttlSeconds, String username); + boolean verifyAuthNumber(String recipientKey, String authNumber); } diff --git a/src/main/java/com/eactive/apim/portal/apps/auth/service/AuthNumberServiceImpl.java b/src/main/java/com/eactive/apim/portal/apps/auth/service/AuthNumberServiceImpl.java index ce08043..b140f76 100644 --- a/src/main/java/com/eactive/apim/portal/apps/auth/service/AuthNumberServiceImpl.java +++ b/src/main/java/com/eactive/apim/portal/apps/auth/service/AuthNumberServiceImpl.java @@ -45,19 +45,31 @@ public class AuthNumberServiceImpl implements AuthNumberService { @Override @Transactional(noRollbackFor = AuthNumberException.class) public String sendRequestAuthNumber(String recipientKey, String msgType) { - return sendRequestAuthNumber(recipientKey, msgType, authNumberExpirationTime); + return sendRequestAuthNumber(recipientKey, msgType, authNumberExpirationTime, null); + } + + @Override + @Transactional(noRollbackFor = AuthNumberException.class) + public String sendRequestAuthNumber(String recipientKey, String msgType, String username) { + return sendRequestAuthNumber(recipientKey, msgType, authNumberExpirationTime, username); } @Override @Transactional(noRollbackFor = AuthNumberException.class) public String sendRequestAuthNumber(String recipientKey, String msgType, int ttlSeconds) { + return sendRequestAuthNumber(recipientKey, msgType, ttlSeconds, null); + } + + @Override + @Transactional(noRollbackFor = AuthNumberException.class) + public String sendRequestAuthNumber(String recipientKey, String msgType, int ttlSeconds, String username) { logger.info("Sending auth number to: {} via {} (ttl={}s)", recipientKey, msgType, ttlSeconds); validateResendTime(recipientKey); String authNumber = generator.generateAuthNumber(); - MessageRecipient recipient = createMessageRecipient(recipientKey, msgType); + MessageRecipient recipient = createMessageRecipient(recipientKey, msgType, username); messageSender.sendAuthMessage(recipient, authNumber, msgType); storage.saveAuthNumber(recipientKey, authNumber, @@ -99,9 +111,13 @@ public class AuthNumberServiceImpl implements AuthNumberService { }); } - private MessageRecipient createMessageRecipient(String recipientKey, String msgType) { + private MessageRecipient createMessageRecipient(String recipientKey, String msgType, String username) { MessageRecipient recipient = new MessageRecipient(); recipient.setUserId(recipientKey); + // 메시지 템플릿 %USER_NAME% 치환용. 비어 있으면 MessageSendService 가 파라미터 자체를 넣지 않는다. + if (username != null && !username.trim().isEmpty()) { + recipient.setUsername(username); + } if ("SMS".equalsIgnoreCase(msgType)) { recipient.setPhone(recipientKey); } else if ("EMAIL".equalsIgnoreCase(msgType)) { diff --git a/src/main/java/com/eactive/apim/portal/apps/user/facade/AuthFacadeImpl.java b/src/main/java/com/eactive/apim/portal/apps/user/facade/AuthFacadeImpl.java index b4ec6b1..0c3776e 100644 --- a/src/main/java/com/eactive/apim/portal/apps/user/facade/AuthFacadeImpl.java +++ b/src/main/java/com/eactive/apim/portal/apps/user/facade/AuthFacadeImpl.java @@ -17,6 +17,12 @@ public class AuthFacadeImpl implements AuthFacade { private final AuthNoticeProperties authNoticeProperties; private static final Logger log = LoggerFactory.getLogger(AuthFacadeImpl.class); + /** + * 회원가입·아이디/비밀번호 찾기 등 로그인 이전 흐름은 수신자 이름을 알 수 없으므로 + * 메시지 템플릿 %USER_NAME% 자리에 넣을 기본값. + */ + private static final String GUEST_USER_NAME = "guest"; + /** * 인증 요청 @@ -43,7 +49,7 @@ public class AuthFacadeImpl implements AuthFacade { } try { - String generatedAuthNumber = authNumberService.sendRequestAuthNumber(recipientKey, msgType); + String generatedAuthNumber = authNumberService.sendRequestAuthNumber(recipientKey, msgType, GUEST_USER_NAME); response.setValid(true); response.setMessage("인증번호를 발송하였습니다."); // 테스트 환경(PTL_PROPERTY auth.test-notice.enabled=true, prod 제외)에서만 인증번호를 응답에 노출