diff --git a/pom.xml b/pom.xml index c953039..a284527 100644 --- a/pom.xml +++ b/pom.xml @@ -89,6 +89,15 @@ org.springframework.boot spring-boot-starter-security + + org.springframework.boot + spring-boot-starter-validation + + + net.nurigo + sdk + 4.3.0 + diff --git a/src/main/java/com/Application.java b/src/main/java/com/Application.java index b23b3e3..27f8c10 100644 --- a/src/main/java/com/Application.java +++ b/src/main/java/com/Application.java @@ -7,7 +7,8 @@ @SpringBootApplication @ServletComponentScan -@MapperScan("com.barogagi") +//@MapperScan("com.barogagi") +@MapperScan(basePackages = "com.barogagi.**.mapper") // MyBatis 매퍼만 있는 경로로 제한 public class Application { public static void main(String[] args){ SpringApplication.run(Application.class, args); diff --git a/src/main/java/com/barogagi/approval/controller/ApprovalController.java b/src/main/java/com/barogagi/approval/controller/ApprovalController.java index c8e1718..8ab1cba 100644 --- a/src/main/java/com/barogagi/approval/controller/ApprovalController.java +++ b/src/main/java/com/barogagi/approval/controller/ApprovalController.java @@ -6,6 +6,8 @@ import com.barogagi.approval.vo.ApprovalSendVO; import com.barogagi.approval.vo.ApprovalVO; import com.barogagi.response.ApiResponse; +import com.barogagi.sendSms.dto.SendSmsVO; +import com.barogagi.sendSms.service.SendSmsService; import com.barogagi.util.EncryptUtil; import com.barogagi.util.InputValidate; import io.swagger.v3.oas.annotations.Operation; @@ -22,26 +24,26 @@ public class ApprovalController { private static final Logger logger = LoggerFactory.getLogger(ApprovalController.class); - private final InputValidate inputValidate; - private final EncryptUtil encryptUtil; - private final AuthCodeService authCodeService; - private final ApprovalService approvalService; + @Autowired + private InputValidate inputValidate; - private final String API_SECRET_KEY; + @Autowired + private EncryptUtil encryptUtil; @Autowired - public ApprovalController(Environment environment, - InputValidate inputValidate, - EncryptUtil encryptUtil, - AuthCodeService authCodeService, - ApprovalService approvalService){ + private AuthCodeService authCodeService; - this.API_SECRET_KEY = environment.getProperty("api.secret-key"); + @Autowired + private ApprovalService approvalService; + + @Autowired + private SendSmsService sendSmsService; + + private final String API_SECRET_KEY; - this.inputValidate = inputValidate; - this.encryptUtil = encryptUtil; - this.authCodeService = authCodeService; - this.approvalService = approvalService; + @Autowired + public ApprovalController(Environment environment){ + this.API_SECRET_KEY = environment.getProperty("api.secret-key"); } @Operation(summary = "인증번호 발송", description = "휴대전화번호로 인증번호 발송하는 기능입니다.") @@ -66,6 +68,10 @@ public ApiResponse approvalTelSend(@RequestBody ApprovalSendVO approvalSendVO) { message = "인증번호를 발송할 전화번호를 입력해주세요."; } else{ + + // 전화번호 + String recipientTel = approvalSendVO.getTel(); + // 인증번호를 DB에 INSERT 전에, 전에 발송된 기록들은 flag UPDATE 처리 approvalVO.setCompleteYn("N"); approvalVO.setType(approvalSendVO.getType()); @@ -80,20 +86,34 @@ public ApiResponse approvalTelSend(@RequestBody ApprovalSendVO approvalSendVO) { String authCode = authCodeService.generateAuthCode(); logger.info("@@ authCode={}", authCode); + // 인증번호 메시지 발송 + SendSmsVO sendSmsVO = new SendSmsVO(); + sendSmsVO.setRecipientTel(recipientTel); + String messageContent = "인증번호는 [" + authCode + "] 입니다."; + sendSmsVO.setMessageContent(messageContent); + boolean sendMessageResult = sendSmsService.sendSms(sendSmsVO); + logger.info("@@ sendMessageResult={}", sendMessageResult); + // 인증번호 암호화 approvalVO.setAuthCode(encryptUtil.hashEncodeString(authCode)); // 인증번호를 DB에 insert - int insertResult = approvalService.insertApprovalRecord(approvalVO); - logger.info("@@ insertResult={}", insertResult); - if(insertResult > 0) { - // 인증번호 발송 로직 - resultCode = "200"; - message = "인증번호가 발송되었습니다."; - - } else{ - resultCode = "102"; - message = "오류가 발생하였습니다."; + if(sendMessageResult){ + approvalVO.setMessageContent(sendSmsVO.getMessageContent()); + int insertResult = approvalService.insertApprovalRecord(approvalVO); + logger.info("@@ insertResult={}", insertResult); + if(insertResult > 0) { + // 인증번호 발송 로직 + resultCode = "200"; + message = "인증번호 발송에 성공하었습니다."; + + } else{ + resultCode = "102"; + message = "오류가 발생하였습니다."; + } + } else { + resultCode = "103"; + message = "인증번호 발송에 실패하였습니다."; } } } else { diff --git a/src/main/java/com/barogagi/approval/vo/ApprovalVO.java b/src/main/java/com/barogagi/approval/vo/ApprovalVO.java index 8dbe65b..021df3b 100644 --- a/src/main/java/com/barogagi/approval/vo/ApprovalVO.java +++ b/src/main/java/com/barogagi/approval/vo/ApprovalVO.java @@ -19,4 +19,7 @@ public class ApprovalVO extends DefaultVO { // 타입 private String type = ""; + + // 메시지 내용 + private String messageContent = ""; } diff --git a/src/main/java/com/barogagi/member/join/dto/NickNameDTO.java b/src/main/java/com/barogagi/member/join/dto/NickNameDTO.java index 2de766b..5fd7f2b 100644 --- a/src/main/java/com/barogagi/member/join/dto/NickNameDTO.java +++ b/src/main/java/com/barogagi/member/join/dto/NickNameDTO.java @@ -1,9 +1,11 @@ package com.barogagi.member.join.dto; import com.barogagi.config.vo.DefaultVO; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.*; @Getter @Setter diff --git a/src/main/java/com/barogagi/member/join/dto/UserIdCheckDTO.java b/src/main/java/com/barogagi/member/join/dto/UserIdCheckDTO.java index 92b4026..2c13a32 100644 --- a/src/main/java/com/barogagi/member/join/dto/UserIdCheckDTO.java +++ b/src/main/java/com/barogagi/member/join/dto/UserIdCheckDTO.java @@ -1,9 +1,11 @@ package com.barogagi.member.join.dto; import com.barogagi.config.vo.DefaultVO; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.*; @Getter @Setter diff --git a/src/main/java/com/barogagi/member/login/dto/LoginDTO.java b/src/main/java/com/barogagi/member/login/dto/LoginDTO.java index 80da97e..5038b2b 100644 --- a/src/main/java/com/barogagi/member/login/dto/LoginDTO.java +++ b/src/main/java/com/barogagi/member/login/dto/LoginDTO.java @@ -2,9 +2,11 @@ import com.barogagi.config.vo.DefaultVO; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.*; @Getter @Setter @@ -15,7 +17,7 @@ public class LoginDTO extends DefaultVO { @NotBlank(message = "비밀번호는 필수 입력값입니다.") @Size(min = 8, max = 20, message = "비밀번호는 8자 이상 20자 이하여야 합니다.") - @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]+$", + @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]+$", message = "비밀번호는 영문, 숫자, 특수문자를 포함해야 합니다.") @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private String password = ""; diff --git a/src/main/java/com/barogagi/sendSms/dto/SendSmsVO.java b/src/main/java/com/barogagi/sendSms/dto/SendSmsVO.java new file mode 100644 index 0000000..cbccae3 --- /dev/null +++ b/src/main/java/com/barogagi/sendSms/dto/SendSmsVO.java @@ -0,0 +1,12 @@ +package com.barogagi.sendSms.dto; + +import com.barogagi.config.vo.DefaultVO; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class SendSmsVO extends DefaultVO { + private String recipientTel = ""; + private String messageContent = ""; +} diff --git a/src/main/java/com/barogagi/sendSms/service/SendSmsService.java b/src/main/java/com/barogagi/sendSms/service/SendSmsService.java new file mode 100644 index 0000000..721c51d --- /dev/null +++ b/src/main/java/com/barogagi/sendSms/service/SendSmsService.java @@ -0,0 +1,62 @@ +package com.barogagi.sendSms.service; + +import com.barogagi.sendSms.dto.SendSmsVO; +import net.nurigo.sdk.NurigoApp; +import net.nurigo.sdk.message.exception.NurigoMessageNotReceivedException; +import net.nurigo.sdk.message.model.Message; +import net.nurigo.sdk.message.service.DefaultMessageService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; + +@Service +public class SendSmsService { + + private static final Logger logger = LoggerFactory.getLogger(SendSmsService.class); + + private String SEND_TEL = ""; + private String API_KEY = ""; + private String API_SECRET_KEY = ""; + + public SendSmsService(Environment environment) { + this.SEND_TEL = environment.getProperty("send.sms.tel"); + this.API_KEY = environment.getProperty("send.sms.api-key"); + this.API_SECRET_KEY = environment.getProperty("send.sms.api-secret-key"); + } + + /** + * SMS 발송 + * @param sendSmsVO + * @return boolean + */ + public boolean sendSms(SendSmsVO sendSmsVO){ + + boolean result = true; + + DefaultMessageService messageService = NurigoApp.INSTANCE.initialize(API_KEY, API_SECRET_KEY, "https://api.solapi.com"); + // Message 패키지가 중복될 경우 net.nurigo.sdk.message.model.Message로 치환하여 주세요 + Message message = new Message(); + message.setFrom(SEND_TEL); + message.setTo(sendSmsVO.getRecipientTel()); + message.setText(sendSmsVO.getMessageContent()); + + try { + // send 메소드로 ArrayList 객체를 넣어도 동작합니다! + messageService.send(message); + result = true; + + } catch (NurigoMessageNotReceivedException exception) { + // 발송에 실패한 메시지 목록을 확인할 수 있습니다! + logger.info("발송에 실패한 메시지 목록: {}", exception.getFailedMessageList()); + logger.error(exception.getMessage()); + result = false; + + } catch (Exception exception) { + logger.error(exception.getMessage()); + result = false; + } + + return result; + } +} diff --git a/src/main/resources/mapper/ApprovalMapper.xml b/src/main/resources/mapper/ApprovalMapper.xml index 15ccc3e..8839b73 100644 --- a/src/main/resources/mapper/ApprovalMapper.xml +++ b/src/main/resources/mapper/ApprovalMapper.xml @@ -14,8 +14,8 @@