React 이메일 인증 + 타이머

Hee·2023년 6월 7일
1

기존에는 회사 코드와 회사 이메일로 제한된 사용자에게만 가입을 받던 서비스였는데, 일반 사용자들에게도 오픈을 하게 되었다.
이 과정에서 유효하지 않은 이메일로 가입하는 사용자를 막기 위해 이메일 인증을 구현하였다.

우선, 기존 이메일을 받는 input창에 이메일 인증 버튼을 붙인다.

   <button
                    className="emailCheckBtn"
                    onClick={onValidMail}
                    disabled={!emailRegExp.test(formValue.email) || isChecked}
                  >
                    이메일 인증
                  </button>

위 이메일 인증 버튼이 비활성화되는 조건은
입력한 이메일이 이메일 형식에 맞지 않을 때와 이메일 인증을 완료한 이후이다.

인증코드는 3분 후, 데이터 베이스에서 삭제된다.
이를 사용자에게 보여주기 위해 3분 타이머를 제공하였다.

이메일 인증 버튼을 누르면,

  const onValidMail = useCallback(
    e => {
      e.preventDefault();
      fetch(api.emailCheck, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json;charset=utf-8' },
        body: JSON.stringify({
          userEmail: formValue.email,
        }),
      }).then(res => {
        if (res.status === 200) {
          setIsGetCode(true);
          setIsTimer(true);
          setCount(180);
        } else if (res.status === 401) {
          alert('이미 존재하는 이메일입니다.');
        } else if (res.status === 402) {
          alert('이미 인증이 진행중입니다.');
        }
      });
    },
    [formValue]
  );

3분 타이머와 함께 인증코드 입력창이 제공된다.

{isTimer && !isChecked ? (
                    <Timer count={count} setCount={setCount} />
                  ) : null}
                  {isGetCode ? (
                    <>
                      <div className="signUpHeader">
                        <div className="signUpModalText">인증코드</div>
                      </div>
                      <input
                        name="emailCode"
                        value={codeValue}
                        className="codeInput"
                        placeholder="인증코드 4자리를 입력해주세요"
                        onChange={handleEmailCode}
                      />
                      {isChecked ? (
                        <img
                          src={checkImg}
                          alt="확인 완료"
                          className="codeCheckImage"
                        />
                      ) : (
                        <button
                          className="codeCheckBtn"
                          onClick={onValidCode}
                          disabled={!(codeValue && codeValue.length >= 4)}
                        >
                          확인
                        </button>
                      )}
                    </>
                  ) : null}

인증코드 입력 후, 확인 버튼을 누르면 서버에서 확인하게 되고

.then(res => {
      if (res.status === 200) {
        setIsEmailChecked(true);
        setIsChecked(true);
      } else if (res.status === 401) {
        alert('인증번호가 일치 하지 않습니다.');
      }
    });

일치하면 인증코드 확인버튼에 체크표시와 함께 회원가입 필수 입력 항목들이 촤르륵 나오게 된다.

간단 이메일 인증 끝 😀

⏰ 3분 타이머는 useEffect와 setInterval 조합으로 만들 수 있었다.

  • 설정된 시간 간격마다 setInterval 콜백이 실행되고 count를 1씩 감소 시킨다.
  • count가 바뀔 때 마다 useEffect가 재실행된다.
  • count가 0이 되면 setInterval을 멈춘다.
  • 이를 시, 분 형식으로 바꾸어 표시해준다.
const Timer = ({ count, setCount }) => {
  const formatTime = time => {
    const minutes = Math.floor(time / 60);
    const seconds = time % 60;
    return `${minutes.toString().padStart(2, '0')}:${seconds
      .toString()
      .padStart(2, '0')}`;
  };

  useEffect(() => {
    const id = setInterval(() => {
      setCount(count => count - 1);
    }, 1000);

    if (count === 0) {
      clearInterval(id);
    }
    return () => clearInterval(id);
  }, [count]);

  return (
    <div className="timerContainer">
      <span className="timerText">{formatTime(count)}</span>
    </div>
  );
};
profile
*^^*

11개의 댓글

comment-user-thumbnail
2024년 3월 21일

소스좀 받아 볼수 있을까요?

1개의 답글
comment-user-thumbnail
2024년 4월 8일

혹시 저도 소스 받을 수 있을까요??

1개의 답글
comment-user-thumbnail
2024년 4월 16일

안녕하세요 dnehdrbs10@naver.com 제 이메일인데 혹시 저도 소스좀 받을 수 있을까요 .. 제가 첫 프로젝트에서 이메일 인증을 해야할거같은데 소스코드 볼 수 있으면 너무 감사할거같습니다

1개의 답글
comment-user-thumbnail
2024년 5월 6일

안녕하세요 이번에 프로젝트로 로그인을 구현하고 있는데 막히는 도중 이 글을 발견해서 혹시 지금이라도 가능하다면 소스코드 공유 부탁드립니다.! creworroad@naver.com 감사합니다

답글 달기