ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JavaScript] SpringBoot 프로젝트 : 회원가입 기능 구현 - 이메일 본인인증 이메일 폼(<select>,<option>, JavaScript 변수, scope)
    프로젝트/기능 정리 2023. 7. 7. 17:02

    목적

    • 게시판 형식 웹사이트 개발 시 회원가입 기능 구현 정리
    • 아이디 중복확인, 비밀번호 확인, 이메일 인증번호 등 세부 기능 정리

     

    지난글까지는 회원가입 과정 중 아이디 중복확인 및 비밀번호 재확인, 전화번호 자동 하이픈(-) 기능을 살펴봤다.

     

    이번 글부터는 이메일 인증 관련 부분에 대해 다뤄보자.

     

    [데이터 흐름도]

    데이터 흐름도는 다음과 같다.

     

    회원가입 데이터 흐름도

     

    [JSP]

    먼저 폼을 어떻게 구성했는지 보겠다.

     

    이메일 처리 전반 또한 이전 프로젝트에서 팀원이 작성해둔 코드를 거의(일부 변경) 그대로 가져온 것이다.

     

    서칭해보니 팀원도 다른 포스트를 참고하여 작성한 것 같아 첨부한다.

     

    참고 : https://devofroad.tistory.com/43

     

    <li>
        <label for="user_email"><small>이메일</small></label>
        <input type="text" id="user_email" class = "align-left" required placeholder = "이메일 입력">
        <div id = "confrimEmail">
            <span id="middle"><small>@</small></span>
            <select id="email_address" name="email_address" title="이메일 선택" class="email_address">
                <option value="naver.com">naver.com</option>
                <option value="gmail.com">gmail.com</option>
                <option value="daum.net">daum.net</option>
                <option value="hanmail.net">hanmail.net</option>
                <option value="nate.com">nate.com</option>
                <option value="direct">직접입력</option>
            </select>
        <button type="button" class="btn btn-primary checkSome" id="mail-Check-Btn">전송</button>
        </div>
        <input type="text" id="email_direct" name="email_direct" placeholder="이메일 입력"/>
        <input type="hidden" id="mem_email" name="mem_email" value="">
    </li>

    폼을 작성한 태그는 위와 같다.

     

    일부 디자인을 위한 태그는 제외했다.

     

    이메일 폼

     

    위 태그에 대한 결과물 이미지는 위와 같다.

     

    크게 보면 세 가지 구성으로 이루어져 있다고 볼 수 있다.

     

    첫 번째는 아래 <input> 태그로, 회원가입자가 이메일 앞자리를 입력하는 부분이다. 

    <input type="text" id="user_email" class = "align-left" required placeholder = "이메일 입력">

    두 번째는 아래 <select> 태그로, 어떤 이메일 주소를 사용할 것인지 선택하는 부분이다.

    <span id="middle"><small>@</small></span>
    <select id="email_address" name="email_address" title="이메일 선택" class="email_address">
        <option value="naver.com">naver.com</option>
        <option value="gmail.com">gmail.com</option>
        <option value="daum.net">daum.net</option>
        <option value="hanmail.net">hanmail.net</option>
        <option value="nate.com">nate.com</option>
        <option value="direct">직접입력</option>
    </select>

    마지막은 히든 처리된 <input> 태그로, 가입자가 입력한 이메일 앞부분과 <select>된 <option> 값인 주소를 연결해서 담아두고 있는태그가 되겠다.

    <input type="hidden" id="mem_email" name="mem_email" value="">

    이 과정은 JS에서 이루어지니 JS 코드를 보자.

     

     

    [JavaScript]

    가장 먼저 "직접입력"의 경우 해당 <option>을 선택했을 때만 UI가 표시되어야 한다.

     

    기본값은 naver.com이기 때문에 숨겨줬다.

    $(function(){
        $("#email_direct").hide();
    
    //이하 코드 생략

    다음으로는 가입자가 입력한 메일과 @ 그리고 주소를 합쳐주기 위해 함수를 만들었다.

        function email(){
            let email = $("#user_email").val();
            let middle = $("#middle").text();
            var address;
    
            if($("#email_address").val()=="direct"){
                address = $("#email_direct").val();
            }else{
                address = $("#email_address").val();
            }
    
            if(email!='' && address!=''){
                $("#mem_email").val(email+middle+address);
            }
        };

    email이라는 변수를 생성하고 id가 user_email인 태그의 입력값을 가져와서 담아줬다.

     

    middle은 '@'인데 직접 문자로 넣어도 된다.

     

    다음으로 address라는 변수를 선언해주고 <select> 태그의 <option> 값이 direct인 경우 회원이 입력한 값을, 그 외의 경우 회원이 선택한 <option> 값을 담아줬다.

     

    마지막으로 email 변수와 address 변수가 비어있지 않은 경우, 즉 둘 다 값이 있는 상태인 경우 회원이 이메일을 입력한 것으로 보고 히든 처리 된 <input>태그에 aaaaa@xxxx.mmm 형태로 담아줬다.

     

    리뷰를 하다보니 위 코드와 UI가 살짝 매치되지 않는 부분이 있었다.

     

    direct 선택

     

    UI상으로 보면 이메일 전체를 입력해야될 것처럼 보인다(aaaaa@xxxx.mmm 형태).

     

    그러나 코드를 보면 address 변수에 email_direct라는 id의 <input> 태그 값을 그대로 담고 있으니, 제대로 된 이메일 형식이 되려면 회원은 윗 칸에 본인 이메일 앞자리를 입력하고, 아래 칸엔 xxxx.mmm형태만 입력해야 한다.

     

    디자인 상 전체 입력을 유도하는 것처럼 보이니 조금 수정해보자면, 우선 해당 태그의 placeholder에 명확하게 '전체 이메일 입력'을 넣어줘야겠다.

     

    전체 이메일 입력

     

    이제 함수를 보자.

        function email(){
            let email = $("#user_email").val();
            let middle = $("#middle").text();
    
            if ($("#email_address").val() == "direct"){
                $("#mem_email").val($("#email_direct").val());
            }else {
                $("#mem_email").val(email + middle + $("#email_address").val());
            }
        };

    간단하게 direct를 선택한 경우, 해당 태그의 값을, 나머지 경우 전과 동일한 처리를 해줬다.

     

    다음은 회원이 이메일을 입력할 때와 <select>의 <option> 값을 변경했을 때 위 함수를 실행하는 부분이다.

        $("#user_email").change(function(){
            email();
        });

    이메일을 입력해서 값이 바뀌고 나면, 만들어둔 함수를 실행시켜 완전한 이메일 주소 형태로 만들어준다.

     

    다음은 <select> 부분이다.

        $("#email_address").change(function() {
            if($("#email_address").val() == "direct"){
                $("#user_email").val('');
                $("#mem_email").val('');
                $("#email_direct").show();
                $(document).on('keyup','#email_direct',function(){
                    email();
                });
            }else{
                $("#email_direct").val('');
                $("#email_direct").hide();			
                email();
            }
        });

    <select>의 <option>값이 바뀌면, 조건에 따라 조금 다른 처리를 진행했다.

     

    직접 입력인 direct를 선택한 경우, 이메일 앞 부분 값과 히든 된 <input>태그의 값을 초기화 하고 직접 입력하는 칸이 보이게 했다.

     

    다음으로 keyup 이벤트가 발생할 때 위에 만들어둔 함수를 실행했다(change가 더 좋을 것 같은 느낌이 들긴 한다).

     

    직접 입력이 아닌 경우 direct에 입력된 값이 있다면 지워주고, 태그를 숨긴 뒤 함수를 실행했다.

     

    이렇게까지 하면 <select> <option>을 이용해서 회원가입자가 이메일을 입력했을 때, 해당 이메일을 완전한 주소로 변경해서 저장해두는 코드까지 완성이다.

     


    마지막은 이메일을 모두 입력하고 전송 버튼을 눌렀을 때를 보자.

        $('#mail-Check-Btn').click(function() {
            if($("#email_address").val()=="direct"){
                if($('#email_direct').val()==''){
                    $('#email_direct').val('').focus();
                    $('#mail-check-warn').html('이메일을 입력해주세요');
                    $('#mail-check-warn').css('color','#fba082');
                    return;
                }
            }else{
                if($('#user_email').val()==''){
                    $('#user_email').val('').focus();
                    $('#mail-check-warn').html('이메일을 입력해주세요');
                    $('#mail-check-warn').css('color','#fba082');
                    return;
                }
            }
            $('#mail-check-warn').html('');
            //이하 코드 생략

    뭐가 많아 보이지만 내용은 간단하다.

     

    전송 버튼이 클릭되었을 때, 이메일을 입력하는 태그들의 값을 확인하고 값이 없을 경우 메시지를 표시한 뒤 리턴하여 이하 코드가 실행되지 않도록 하는 것이 전부다.

     

    값이 있을 경우 이메일을 입력하여 완성된 이메일 주소가 있는 것이므로 아래 코드가 실행된다.

                const email = $('#mem_email').val();
                const checkInput = $('.mail-check-input');
    
                $.ajax({
                    type : 'get',
                    url : '../mailCheck?email='+email,
                    success : function (data) {
                        checkInput.attr('disabled',false);
                        code = data;
                        alert('인증번호가 전송되었습니다.');
                    }			
                });
            }
        });

     email 변수에 위에서 처리한 완성된 이메일 주소를 담아주고 checkInput 변수에는 인증번호를 입력하는 태그를 담아준다.

     

    GET방식으로 서버에 email을 담아서 Ajax 전송을 하고,

     

    성공시 인증번호 입력 태그의 disabled를 해제하고 code라는 변수에 리턴받은 data를 담아준다.

     

    이렇게까지 하면 완성된 이메일을 서버해 전송하는 부분까지 완성이다.

     

    이메일을 전달 받은 서버는 해당 주소로 인증번호를 생성하여 보내게 된다.

     

     

    마무리 하기 전에 위 코드를 보면 조금 이상한 점이 있다.

     

    위 어느 코드에서도 code라는 변수는 선언되어있지 않기 때문이다.

     

    리뷰 과정에서 이상하게 느껴 찾아보았다.

     

    [JavaScript 변수]

    우선 JS에는 세 가지 변수 타입이 있는데, 각 var let const가 그것이다.

     

    [var]

    차이점을 두고 보자면 var은 같은 변수명으로 중복해서 선언도 가능하고, 값을 바꿀 수도 있다.

     

     

    var 중복 선언

     

    값을 바꾸는 것은 다음과 같다.

     

    var 값 변경

     

    [let]

    let는 값을 변경할 수는 있지만, 중복해서 선언은 할 수 없다.

     

    let 중복 선언

     

    [const]

    const는 중복 선언도 안되고, 값도 변경할 수 없다.

     

    const 중복 선언

     

    const 값 변경

     

    또 다른 차이점은 변수를 참조할 수 있는 범위가 다르다는 것이다.

     

    var은 function-level scope로 함수 내부에 선언된 변수만 지역변수로 간주한다.

     

    함수레벨 스코프 예시

     

    반대로 말하면 함수 내부가 아닌 곳에 var로 선언된 변수는 전역변수가 된다는 뜻이다. 즉, 어디서나 참조(접근) 가능하다는 것.

     

    예를 들어, 함수가 아닌 그냥 조건문이나, 위 Ajax처럼 특정 코드 내부라거나하는 모든 경우, 함수에서 선언된 var 변수가 아니기 때문에 전역변수로 취급된다.

     

    let와 const는 위 이미지에도 나와 있듯, block-level scrope로 함수뿐 아니라 다른 코드 내부에서 선언되어도 지역변수가 된다.

    블록레벨 스코프 예시 - let

     

     

    블록레벨 스코프 예시 - const

     

    이제 다시 돌아가서,

    success : function (data) {
        checkInput.attr('disabled',false);
        code = data;
        alert('인증번호가 전송되었습니다.');
    }

    이 선언되지 않은 변수 code 가 어떻게 가능한지 보자.

     

    키워드 없이 변수 사용 설명

     

    위 설명은 아래 사이트에서 가져온 것이다.

     

    참고 : https://www.tutorialsteacher.com/javascript/javascript-variable

     

    설명을 보면 변수는 var 이나 let 키워드 없이 선언하거나 초기화 할 수 있다고 하는데, 대신 var 키워드 없이 선언된 변수에는 무조건 값을 할당해야 한다고 써있다.

     

    이렇게 var 키워드 없이 선언된 변수는 어디서 선언되었든 전역변수(global variables)가 된다.

     

    정리해서 보면

    code = data;

    이 부분은 code라는 변수가 var이나 let 키워드 없이 선언되어 있는 것인데, 생성과 동시에 값을 할당했기 때문에 오류가 나지 않은 것이고, 전역변수로 인정되어 어디서든 변수에 접근할 수 있는 상태가 되었다고 할 수 있다.

     

    선언된 위치에 관계 없이 전역변수라기에 설마 function 안에서도 그런가 싶어 테스트 해보니 그랬다.

     

    키워드 없이 function 선언 테스트

     

    그러나 이렇게 변수를 관리하는 것은 별로 좋은 방법이 아니라고 하니, 상황에 따라 필요한 키워드를 선택해 변수를 선언하는 것이 좋겠다.

     

     

    이렇게 해서 이메일 폼과 <select> <option> 태그 값을 JS에서 처리하는 것, 논외로 JS 변수와 스코프에 대해서 다뤘다.

     

    다음 글에서는 이메일을 전달 받은 서버에서 인증번호를 생성하고 메일을 보내는 과정을 알아보도록 하겠다.

     

Designed by Tistory.