본문 바로가기
JavaScript

[JavaScript] 정규식을 활용하여 이메일 로그인 시 예외처리하기

by teamnova 2023. 5. 8.
728x90

안녕하세요. 웹페이지에서 로그인/회원가입 시 대부분의 서비스들은 글자의 종류와 길이에 대한 제한을 두고 유저가 입력을 할 때마다 실시간으로 입력 조건을 만족시켰는지 표시해주는데요. 이번 시간에는 정규식을 활용한 예외 처리를 통해 이메일과 비밀번호로 로그인을 할 때 응용 할 수 있는 기능을 구현하려 합니다.

 

 

우선 다음과 같이 html 태그들을 먼저 작성하였습니다.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
        <script defer="defer" src="./index.js"></script>
        <link rel="stylesheet" href="./index.css"> 
    </head>
    <body>                             
      <div class="div_block">
        <span id = "email_text" class="text" for="email">
            이메일
        </span>
        <input id = "email_input" onkeyup='printEmail()' class="input" id="email" type="text" placeholder="">
        <span id = "email_check" class = "warn_text">
        유효한 이메일 주소를 입력하세요.</span>  
      </div>         
      <div class="div_block">
        <span id = "pw_text" class="text" for="password">
            비밀번호
        </span>
        <input id = "pw_input" onkeyup = 'printPw()' class="input" id="password" type="password" placeholder="">
        <span id = "pw_check" class = "warn_text">
        8~15자 이내로 입력하세요.</span>
      </div>          
      <button id = "login_btn" class="btn" disabled 
      type="button">
          로그인
      </button>             
    </body>
</html>

이메일과 비밀번호 입력창에는 키보드를 눌렀다가 뗐을 때 발생하는 이벤트인 onkeyup시에 각각 printEmail, printPw라는 자바스크립트 함수가 작동하도록 처리함으로써 유저가 입력을 감지하고, 이에 따라 로직이 작동하도록 처리하였습니다. 두 함수에 대해서는 아래에서 좀 더 자세히 설명드리겠습니다. 

로그인 버튼의 경우 처음에는 버튼이 비활성화 되었다가, 이메일과 비밀번호의 입력조건이 일치할 경우에만 활성화 되게 처리하기 위해 button 태그에 disabled 속성을 추가하였습니다.

 

 

다음 CSS 코드입니다.

.div_block {
	/* ui를 감싸는 div 태그에 flexbox 설정 */
    display: flex;
    flex-direction: column;
   
  }
  .text {
  	/* 글자 크기 설정 */
    font-size: 14px;
    /* 글자 굵기 설정 */
    font-weight: bold;
    /* 글자 색 설정 */
    color: #4b5563;
    /* 텍스트 아래에 여백 설정 */
    margin-bottom: 0.25rem;
  }
  .input {
  	/* 입력창 테두리 굵기, 모양, 색 설정 */
    border: 1px solid #cbd5e0;
    /* 입력창의 꼭짓점 둥글게 처리 */
    border-radius: 0.25rem;          
    /* 입력창 안쪽에 여백 설정 */
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
    padding-left: 0.75rem;
    padding-right: 0.75rem;
    /* 입력창 색 설정 */
    color: #4b5563;       
    /* 입력창 길이 지정 */
    width : 18.75rem;            
  }

우선 전체 ui를 감싸는 div_block과 이메일, 비밀번호의 텍스트 클래스인 text, 입력창에 대한 클래스인 input입니다.

text와 input의 경우에는 길이, 색, 여백등의 디자인 처리를 하였고, div_block의 경우 flexbox의 display:flex 속성을 사용하여 예시 코드를 구성하는 ui들이 순서대로 쌓이도록 구성하였습니다.

또한 flex-direction: column 속성을 활용해 가로가 아닌 세로로 나열되도록 처리하였습니다.

 

 

다음으로 입력 조건이 일치하지 않을 때 입력창 하단에 보여지는 warn_text 클래스와 로그인 버튼에 대한 css 코드입니다.

 .warn_text {
 	/* 텍스트 안보이게 설정 */
    visibility: hidden;

	/* 텍스트 크기, 굵기, 색 설정 */
    font-size: 12px;
    font-weight: 600;
    color: #EF4444;
    /* 텍스트 위, 아래에 여백 설정 */
    margin-top : 0.25rem;
    margin-bottom: 1rem;
  }

  .btn {
  	/* 버튼 색상 */
    background-color: #3B82F6;
    /* 텍스트의 색상, 굵기 */
    color: #fff;
    font-weight: 700;
    /* 버튼의 상/하/좌/우 여백 */
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
    padding-left: 1rem;
    padding-right: 1rem;
    /* 버튼의 꼭짓점 둥글게 처리 */
    border-radius: 0.25rem;    
    /* 버튼색이 변할 때 0.2초의 딜레이 처리 */
    transition: background-color 0.2s ease-out;
  }

  /* 버튼에 마우스 커서가 올라가 있을 때의 색깔 */
  .btn:hover {
    background-color: #2563EB;
  }

  /* 버튼을 클릭했을 때 버튼 주변에 그림자 생성 (클릭 되었다는거 알리는 용) */
  .btn:focus {
  	/* 버튼 그림자의 색상(59, 130, 246)과 투명도(0.5) 지정  */
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
  }
  
  /* 버튼이 비활성화 되어 있을 때 */
  .btn:disabled {
  	/* 버튼의 투명도 설정 (0일수록 투명, 1일수록 불투명) */
    opacity: 0.5;
    /* 버튼이 마우스 이벤트를 받지 못하게 처리 */
    pointer-events: none;
  }

warn_text의 경우 입력조건이 일치하지 않을 때만 보여야 하므로 우선 처음에는 안보이게 처리합니다. 로그인 버튼 .btn:disabled 속성을 넣어 비활성화 되어 있을 때는 불투명하게 만들고 pointer-events를 none으로 처리하여 마우스 이벤트를 받지 못하게 처리합니다.

 

 

마지막으로 자바스크립트 코드입니다.

 

우선 이메일을 제대로 입력했는지 실시간으로 체크하는 코드입니다.

// 이메일 실시간 체크
function printEmail() {     
    
    // 이메일 입력창, 이메일 입력조건 불만족 시 하단에 표시되는 경고 텍스트 변수에 할당
    const email = document.getElementById('email_input');    
    const email_check = document.getElementById('email_check');
  
  	// 입력창의 값이 이메일 형태와 맞지 않게 입력된 경우
    if(!isEmail(email.value)){	
  		
        // 이메일 입력창의 테두리 빨간색으로 변경
        email.style.borderColor = '#EF4444';
        // 입력창 하단의 경고 텍스트 보이게
        email_check.style.visibility = 'visible';               
    }
    // 이메일 형태에 적합하게 입력된 경우
    else {
    	// 테두리 색 원래대로 변경
        email.style.borderColor = '#9CA3AF';
        // 경고 텍스트 안보이게 처리
        email_check.style.visibility = 'hidden';        
  
    // 로그인 버튼 활성화 여부를 체크하는 함수 선언
    btnCheck()
    }       

  }
  
  //이메일 정규식 체크하는 함수
  function isEmail(asValue) {
  
  	// 이메일 형식에 맞게 입력했는지 체크
    let regExp = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i;
  
  	
    return regExp.test(asValue); // 형식에 맞는 경우에만 true 리턴	
  
  }

printEmail 함수에서는 이메일이 제대로 입력되었는지 여부에 따라 입력창의 색상, 경고 텍스트의 표시 유무를 결정합니다.

isEmail은 정규식을 통해 이메일을 제대로 입력했는지 여부를 체크하는데 정규식은 특정 패턴의 문자열을 찾기 위해 사용됩니다. 

위 코드에서 사용된 정규식 요소들입니다.

 

- `/^...$/i`: 패턴의 시작과 끝을 나타냅니다.
- `[0-9a-zA-Z]`: 이메일 주소에서 사용될 수 있는 문자셋을 정의합니다. `[...]` 표현식은 문자열의 한 문자를 나타내며, `-`를 사용하여 범위를 지정할 수 있습니다. 여기서는 0부터 9까지의 숫자와 영문 대/소문자를 사용할 수 있습니다.
- `([-_\.]?[0-9a-zA-Z])*`: `*` 메타 문자를 사용하여 앞에 있는 표현식이 0번 이상 반복될 수 있다고 지정합니다. 이메일 주소에서는 `-`, `_`, `.`, 알파벳과 숫자가 사용될 수 있는데, 이러한 문자들은 다른 문자들과 함께 나타날 수도 있고, 나타나지 않을 수도 있습니다. 따라서 `[-_\.]?`와 같이 `?` 메타 문자를 사용하여 이러한 문자가 선택적으로 나타날 수 있도록 합니다.
- `@[0-9a-zA-Z]`: 이메일 주소의 `@` 기호와 그 뒤에 사용될 수 있는 문자열을 정의합니다.
- `([-_\.]?[0-9a-zA-Z])*`: `*` 메타 문자를 사용하여 이메일 주소의 도메인 부분에서 사용될 수 있는 문자열을 정의합니다.
- `\.[a-zA-Z]{2,3}`: 도메인 이름의 마지막 부분을 정의합니다. `.` 문자를 사용하여 이메일 주소에서 도메인 이름을 구분하고, `[a-zA-Z]{2,3}`는 2~3개의 영문 대/소문자로 이루어진 문자열이 됩니다.

정규식에 대한 좀 더 자세한 정보는 아래 링크를 참고해주세요.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_expressions

 

정규 표현식 - JavaScript | MDN

정규 표현식, 또는 정규식은 문자열에서 특정 문자 조합을 찾기 위한 패턴입니다. JavaScript에서는 정규 표현식도 객체로서, RegExp의 exec()와 test() 메서드를 사용할 수 있습니다. String의 match(), matchA

developer.mozilla.org

 

마지막으로 비밀번호를 제대로 입력했는지 체크하는 함수와 로그인 버튼의 활성화 여부를 결정하는 함수의 코드입니다.

  // 비밀번호 실시간 체크
  function printPw() {

	// 비밀번호 입력창, 비밀번호 경고 텍스트 변수 할당
    const pw = document.getElementById('pw_input');
    const pw_check = document.getElementById('pw_check');

	// 입력한 비밀번호가 8~15자 이내가 아닐 경우
    if(pw.value.length < 8 || pw.value.length > 15){	
  		
        // 입력창 테두리 빨간색으로 표시하고 경고 텍스트 보이게 처리
        pw.style.borderColor = '#EF4444';
        pw_check.style.visibility = 'visible';       
        
    }
    else {
    	// 입력창 테두리 원래 색으로 표시하고 경고 텍스트 안보이게 처리
        pw.style.borderColor = '#9CA3AF';
        pw_check.style.visibility = 'hidden';   
    }       
    // 로그인 버튼 활성화 여부 체크
    btnCheck();
  }
  
  // 이메일/비밀번호 입력값이 모두 유효할 때만 버튼 활성화
  function btnCheck() {
	
    // 이메일, 비밀번호, 로그인 버튼 변수 할당
    const email = document.getElementById('email_input').value;       
    const pw = document.getElementById('pw_input');
    const login_btn = document.getElementById('login_btn');
       
    // 이메일 입력조건과 비밀번호 입력조건중 하나라도 만족하지 못하는 경우 로그인 버튼 비활성화
    if (isEmail(email) && (pw.value.length >= 8 && pw.value.length <= 15)) {
            
        login_btn.disabled = false;
    }
    // 모두 만족하는 경우 로그인 버튼 활성화
    else {        
        login_btn.disabled = true;
    }
  }

printPw 함수에서는 비밀번호가 조건에 따라 제대로 입력되었는지 여부에 따라 입력창의 색상, 경고 텍스트의 표시 유무를 결정합니다.

btnCheck 함수는 이메일과 비밀번호의 입력조건이 일치할 경우에만 로그인 버튼을 활성화되게 처리하는 함수입니다. 이메일과 비밀번호의 입력에 따라 입력조건의 일치여부가 실시간으로 변할 수 있으므로 이를 감지하기 위해 btnCheck 함수는 printEmail과 printPw 함수 내부에 배치하였습니다.

 

 

코드를 실행했을 때의 결과 영상입니다.