기존에는 회사 코드와 회사 이메일로 제한된 사용자에게만 가입을 받던 서비스였는데, 일반 사용자들에게도 오픈을 하게 되었다.
이 과정에서 유효하지 않은 이메일로 가입하는 사용자를 막기 위해 이메일 인증을 구현하였다.
우선, 기존 이메일을 받는 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 조합으로 만들 수 있었다.
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>
);
};
소스좀 받아 볼수 있을까요?