728x90
반응형

화면 구성

 

nodemailer 라는 좋은 npm모듈이 있다. 해당 서비스는 클라이언트에서 백엔드(node.js)에 이메일을 보낼거란 신호를 주고, 백엔드 쪽에서 여러 설정( 어떤 메일을 어떤 주소로 보낼건지 등 )을 해놓은 상태에서 메일을 전송하게 되고,

자신이 보낸 메일 인증번호와 클라이언트에서 입력한 인증번호가 같으면 인증이 완료되는 시스템이다.

 

1. 클라이언트 html쪽에선 먼저 이메일 주소 입력창, 인증번호 입력창, 보내기버튼, 인증버튼이 존재한다.

    class 에 d-none 옵션을 추가해서 이메일을 보내지 않은 상태에선 인증번호 입력칸, 인증 버튼이 없도록 했다.

<!--이메일 인증-->
<label class="control-label">{{__('email')}} {{__('auth')}}<span class="text-danger"> *</span> </label>
  <div class="form-group m-b-20">
    <input id="EA" name="EA" type="email" class="form-control form-control-lg inverse-mode" value ="{{email}}" placeholder="{{__('email')}}" data-parsley-error-message=null required >
    <input id="CEA" name="CEA" type="text" class="form-control form-control-lg inverse-model mt-3 d-none" placeholder="{{__('authnum')}}" data-parsley-error-message="{{__('required_detail')}}" data-parsley-errors-container="#err-msg2" required >
  <div class="d-flex justify-content-between align-items-center mt-2">
  <div id="err-msg2" class="text-realred"></div>
    <input type="button" id="sendBtn" class="btn btn-primary btn-block btn-lg ml-auto custombtn" value="{{__('send')}}" onclick="emailSend('EA')">
    <input type="button" id="cerBtn" class="btn btn-primary btn-block btn-lg mt-0 ml-auto custombtn d-none" value="{{__('auth')}}" onclick="emailCer('CEA')">
    <input type="hidden" id="hideCK" name="hideCK" value="">
  </div>
</div>

 

2. 클라이언트 javascript 데이터 검증부분에선 먼저 버튼에 onclick에 붙어있는 함수들을 선언한다. parsley를 사용해 input에 제대로 된 데이터가 들어갔는지 먼저 검증하고 맞으면 아래 함수를 실행하도록 되어있다. 

	// 이메일 전송 기능
	function emailSend(email) {
		var EA = document.getElementsByName(email)[0].value;
		var validateEA = $('#'+email).parsley();
		
		if(validateEA.isValid() == true) {
			emailSendAjax(EA);
		}
		else {
			return alert("{{__('register_email_valid_msg')}}");
		}
	}
	
	// 이메일 인증 기능
	function emailCer(cerNum) {
		var CEA = document.getElementsByName(cerNum)[0].value;
		var validateCEA = $('#'+cerNum).parsley();
		
		if(validateCEA.isValid() == true) {
			emailCerAjax(CEA);
		}
		else {
			alert("{{__('register_auth_enter')}}");
		}
	}

 

3. 클라이언트 javascript 함수 실행부분에선 검증된 데이터가 들어왔을 때, ajax로 백엔드에 데이터를 전송하도록 하였다.

// 이메일 전송 기능
function emailSendAjax(email) {
    $.ajax({
		type: 'POST',
		url: '/email/send',
		dataType: 'json',
		data: {
			EA: email
		}
	}).done(function(data) {
		if (data.result == 'exist') {
			alert(i18nconvert('register_already_msg'));
		}
		else if (data.result == 'send') {
			alert(i18nconvert('register_auth_com_msg'));
			document.getElementsByName('EA')[0].readOnly = true;
			document.getElementById('CEA').classList.remove('d-none');
			document.getElementById('cerBtn').classList.remove('d-none');
			document.getElementById('sendBtn').classList.add('d-none');
			
			clearTimeout(timer);
			stopWatch(300);
		}
		else {
			alert(i18nconvert('register_email_send_fail'));
		}
	});
}

// 이메일 인증 기능
function emailCerAjax(cerNum) {
    $.ajax({
		type: 'POST',
		url: '/email/cert',
		dataType: 'json',
		data: {
			CEA: cerNum
		}
	}).done(function(data) {
		if (data.result == 'success') {
			alert(i18nconvert('register_auth_success'));
			clearTimeout(timer);
			document.getElementsByName('CEA')[0].readOnly = true;
			document.getElementById('err-msg2').innerHTML = i18nconvert('register_auth_success');
			document.getElementsByName('hideCK')[0].value = 'true';
		}
		else {
			alert(i18nconvert('register_auth_fail'));
			document.getElementsByName('CEA')[0].value = null;
			document.getElementsByName('hideCK')[0].value = null;
		}
	});
}

 

백엔드 쪽은 다음 글에서 설명하겠다.

 

@ 인증번호 타이머 기능

   setInterval 함수를 사용해 1초에 한번씩 바꿔주었다.

function stopWatch(TimeSet) {
	timer = setInterval(function(){
		sec = (TimeSet)%60;
		document.getElementById('err-msg2').innerHTML =i18nconvert('register_auth_time') + '&nbsp;' + parseInt(TimeSet/60) + i18nconvert('register_auth_minute') + sec + i18nconvert('register_auth_second') + "." + "<br><a href='javascript:;' id='resend' class='text-white' onclick=emailSend('EA')><u>"+i18nconvert('register_auth_resend')+"</u></a>";
		TimeSet--;
		
		if(TimeSet < 0){
			clearTimeout(timer);
			alert(i18nconvert('register_auth_timeout'));
			document.getElementsByName('EA')[0].value = null;
			document.getElementsByName('CEA')[0].value = null;
			document.getElementsByName('EA')[0].readOnly = false;
			document.getElementsByName('CEA')[0].readOnly = false;
			document.getElementsByName('hideCK')[0].value = null;
			document.getElementsByName('hideCNU')[0].value = null;
			document.getElementById('CEA').classList.add('d-none');
			document.getElementById('cerBtn').classList.add('d-none');
			document.getElementById('sendBtn').classList.remove('d-none');
			document.getElementById('err-msg2').innerHTML = i18nconvert('register_reauth_msg');
		}
    }, 1000);
}
728x90
반응형

+ Recent posts