문자인증 준비
coolSMS
휴대전화 인증 기능을 coolSMS라는 문자발송대행 서비스를 찾아서 구현하게 되었다.
이미지를 클릭하면 coolSMS 페이지로 이동하게 되고,
회원가입 후 API Key 목록으로 이동 후 API KEY를 발급 받은 후
마지막으로 허용 IP 관리에서 설정만 해주면 된다.
build.gradle -> dependencies 의존성 주입
// cool sms 의존성 추가
implementation 'net.nurigo:sdk:4.3.0'
application.properties 설정
#전화번호는 01012345678 형식으로 적어야 한다
coolsms.apikey = api key
coolsms.api-secret = api secret
coolsms.from-number = 전화번호입력
coolsms.domain= https://api.coolsms.co.kr
*** 전화번호는 실제 존재하는 번호로 설정해야 한다.
SmsCertificationUtil 코드
( coolSMS API를 사용하여 인증번호를 전송하는 역할)
@Component
public class SmsCertificationUtil {
@Value("${coolsms.apikey}") // coolsms api 키
private String apiKey;
@Value("${coolsms.api-secret}") // coolsms api 비밀키
private String apiSecret;
@Value("${coolsms.from-number}") // 발신자번호
private String fromNumber;
@Value("${coolsms.domain}") // 도메인 주소
private String domain;
private DefaultMessageService messageService;
@PostConstruct
public void init() {
// Cool SMS 메시지 서비스 초기화
this.messageService = NurigoApp.INSTANCE.initialize(apiKey, apiSecret, domain);
}
// SMS 발송 메서드
public void sendSMS(String to, String certificationCode) {
Message message = new Message();
message.setFrom(fromNumber); // 발신자 번호 설정
message.setTo(to); // 수신자 번호 설정
message.setText("본인확인 인증번호는 " + certificationCode + "입니다."); // 메시지 내용 설정
// 메시지 발송 요청
this.messageService.sendOne(new SingleMessageSendingRequest(message));
}
}
-> API KEY, API SECRET, 발신자 번호와 같은 민감한 정보를 외부 설정 파일(application.properties)에서
주입받아 보안성을 유지하면서도, coolSMS 서비스를 효율적으로 초기화하고 사용할 수 있도록 설계
문자인증 구현
html & JavaScript
<!--휴대전화번호 입력-->
<label for="phone" class="label">휴대전화번호</label>
<div class="phone-group">
<input id="phone" type="text" class="input phone-input" th:field="*{userPhone}"
placeholder="'-' 없이 입력" required>
<button type="button" class="button requestSMS-bnt" onclick="requestSMS()">인증요청</button>
</div>
<div class="serverValidate" th:if="${#fields.hasErrors('userPhone')}" th:errors="*{userPhone}"></div>
<span id="phoneMsg" class="validate"></span>
<!--인증번호 입력-->
<div class="group">
<label for="Authentication" class="label"></label>
<input id="Authentication" type="text" class="input" placeholder="인증번호를 입력하세요" required>
<!--서버에서 발송된 인증번호-->
<input type="hidden" id="randomNum" value="">
<button type="button" class="button checkSMS-bnt"
onclick="checkSMS()">인증번호 확인
</button>
<span id="authMsg" class="validate"></span>
</div>
// 인증번호 전송 요청
function requestSMS() {
const phone = document.getElementById("phone").value; // 사용자 입력 휴대전화 번호
const phoneMsg = document.getElementById("phoneMsg"); // 휴대전화 번호 유효성 메시지
// 휴대전화 번호 정규식: 010으로 시작하며, 뒤에 8자리 숫자가 나옴
const phonePattern = /^010\d{8}$/;
if (!phone) {
alert('휴대전화 번호를 입력해 주세요.');
return;
}
// 휴대전화 번호 유효성 검사
if (!phonePattern.test(phone)) {
phoneMsg.innerHTML = "유효한 휴대전화 번호를 입력해 주세요.";
phoneMsg.style.color = "red";
return;
}
// 유효한 번호라면 메시지를 제거
else {
phoneMsg.innerHTML = "";
}
$.ajax({
type: "POST",
url: "/sms/send",
contentType: "application/json",
data: JSON.stringify({ phoneNumber: phone }), // controller로 보낼 데이터 JSON 형태로 변환
success: function(response) {
console.log("SMS response:", response); // 응답 로그 추가
alert("인증번호가 발송되었습니다.");
document.getElementById("randomNum").value = response.certificationCode; // 인증번호를 hidden input에 저장
startTimer(); // 인증번호 제한시간 시작
},
error: function(xhr, status, error) {
alert("인증번호 발송에 실패했습니다. 다시 시도해주세요.");
}
});
}
// 인증번호 확인
function checkSMS() {
const userCode = document.getElementById("Authentication").value; // 사용자가 입력한 인증번호
const serverCode = document.getElementById("randomNum").value;
if (!userCode) {
alert('인증번호를 입력해 주세요.');
return;
}
if (userCode === serverCode) {
clearInterval(timer); // 타이머 중지
isVerified = true;
alert("인증이 정상적으로 완료되었습니다.");
}
else {
alert("인증번호가 올바르지 않습니다.");
isVerified = false;
}
}
위 두코드를 같이 보면
requestSMS() 함수
- 유효한 번호인지 검사한 후 ajax를 통해 서버로 인증번호 발송요청을 보낸다.
- 서버로부터 인증번호를 받으면 , hidden으로 설정해 놓은 input( randomNum )필드에 저장된다.
checkSMS() 함수
- 사용자가 입력한 인증번호를 서버에서 발송된 번호 (위에서 담은 randomNum )과 비교
- 일치 -> 인증 완료, 그렇지 않으면 오류메세지
SignController
// 회원가입 시 휴대전화 인증
// ajax에서 POST 요청한 경로 /sms/send와 매핑
@PostMapping("/sms/send")
@ResponseBody
public Map<String, Object> sendSMS(@RequestBody Map<String, String> param) {
// 응답을 담을 Map 객체 생성
Map<String, Object> response = new HashMap<>();
try {
// param에서 userPhone 키의 값 추출, 휴대전화 번호 저장 (사용자가 입력한 번호)
String phoneNumber = param.get("phoneNumber");
// 인증번호 생성 요청
String certificationCode = memberService.generateCertificationCode();
// 생성된 인증번호 -> sms 전송
memberService.sendSMSViaCoolSMS(phoneNumber, certificationCode);
// 성공 응답
response.put("success", true);
response.put("certificationCode", certificationCode);
} catch (Exception e) {
// 실패 응답
response.put("success", false);
response.put("error", "인증번호 발송에 실패했습니다. 다시 시도해주세요.");
}
// 응답 결과 반환
return response;
}
MemberService
// 인증번호 생성 메서드
public String generateCertificationCode() {
Random random = new Random();
int code = 100000 + random.nextInt(900000);
return String.valueOf(code);
}
// Cool SMS API 호출 메서드 -> 실제 메세지 발송 역할
public void sendSMSViaCoolSMS(String phoneNumber, String certificationCode) {
smsCertificationUtill.sendSMS(phoneNumber, certificationCode); // SmsCertificationUtil을 사용하여 SMS 발송
}
이렇게 문자인증 준비를 하기위해 API를 설정하고
문자인증을 하기위해 서버와 사용자와 연결하기 위해 코드를 작성을 마무리 하였다.
그러고 나서 인증요청을 누르니 아래와같이 인증번호가 성공적으로 전송이 되었다!!
이렇게 회원가입은 마무리가 되었다!!