요즘은 회원가입, 로그인 기능이 없는 웹, 앱을 찾는 것이 더 어렵다.
구현은 간단해보인다. form, input, button 태그 정도면 될 것 같다.
그런데, 보안상의 문제로 인해 몇 자 이상을 입력해야한다든지, 특수문자를 꼭 포함해서 입력해야한다든지 등등 다양한 요구 조건을 걸어야할 때가 있다.
이런건 어떻게 구현해야할까?
바로 정규식 표현이라는 것을 통해서 유저의 입력값을 비교할 수 있다.
모든 경우의 수를 전부 설명하자면 굉장히 길어지므로, 필자가 사용한 이메일, 비밀번호 관련 정규식 표현만 설명하겠다.
// 이메일 유효성 검사
if (email.length > 0) {
setEmail((currentValue) => currentValue);
// 정규식 표현으로 유효성 검사(Regular Expression)
const emailRegEx = /^([a-z0-9_\.-]+)@([\da-z-]+)\.([a-z\.]{2,6})$/;
if (!emailRegEx.test(email)) {
setEmailMessage("이메일 형식이 틀렸습니다. 다시 입력해주세요.");
setIsEmail(false);
} else {
setEmailMessage("이메일이 정상적으로 입력되었습니다.");
setIsEmail(true);
}
}
emailRegEx라는 변수에 있는 값이 바로 정규식 표현이다.
/^([a-z0-9_\.-]+)@([\da-z-]+)\.([a-z\.]{2,6})$/
이게 도대체 무슨 의미일까? 그룹별로 뜯어서 살펴보자.
^([a-z0-9_\.-]+) // ex) ab.-34_
a~z의 알파벳, 0~9의 숫자, _ 기호, . 기호, - 기호 중 어떤 것이라도 사용되어야하며, 그 것들로 시작되어야한다(^ 기호의 의미)는 뜻이다.
+는 이 중에서 최소한 하나는 만족해야한다는 것이다.
예를들어, "ab.-34_" 이라는 문자열은 이를 만족한다.
다음은
@
간단하다. @ 기호가 들어가야한다는 뜻이다.
다음은
([\da-z-]+)
처음 봤던 부분이랑 크게 다른 것이 없다.
a~z의 알파벳, - 기호, 0~9의 숫자(/d는 digit으로 0~9를 의미한다) 중 최소 하나는 만족해야한다는 것을 의미한다.
다음은
\.
. 기호가 포함되어야한다는 것이다.
마지막으로
([a-z\.]{2,6})$
a~z의 알파벳, . 기호 중 하나를 사용해서 2자리에서 6자리까지 기입해야하는 것을 의미한다. 그리고 이 문자열로 끝을 내야한다는 것($ 기호)을 의미한다.
따라서, 이 정규식을 유저의 입력값과 비교하면서 우리가 원하는대로 유저의 입력을 유도할 수 있다.
조건을 만족하는 입력은 다음과 같다.
ab.-34_@naver.com
ab.-34_@naver.co.kr
secret-32@h.i.com
이외에도 정말 다양한 예시가 존재할 것이다.
test() 메서드는 아래와 같은 방식으로 사용한다.
정규 표현식.test(입력한 문자열)
입력한 문자열이 정규 표현식의 조건에 맞으면 true, 안 맞으면 false를 반환한다.
이를 통해서 아래와 같은 방법으로 유효성 검사를 할 수 있다.
// 유저의 입력을 받아옴
setEmail((currentValue) => currentValue);
// 기준이 될 정규식 표현
const emailRegEx = /^([a-z0-9_\.-]+)@([\da-z-]+)\.([a-z\.]{2,6})$/;
// 조건에 맞지 않으면 통과 못하고, 맞으면 통과
if (!emailRegEx.test(email)) {
setEmailMessage("이메일 형식이 틀렸습니다. 다시 입력해주세요.");
setIsEmail(false);
} else {
setEmailMessage("이메일이 정상적으로 입력되었습니다.");
setIsEmail(true);
}
혹시나 state의 비동기 처리 때문에 이 방법에 문제가 생긴다면 여기에 해결 방법을 적어놓았으니 참고부탁드립니다.
이메일 유효성 검사
/^([a-z0-9_\.-]+)@([\da-z-]+)\.([a-z\.]{2,6})$/
비밀번호 유효성 검사
/^(?=.*[a-zA-Z])(?=.*[!@#$%^])(?=.*[0-9]).{8,25}$/
이 외에도 다양한 정규식이 있고, 개발자가 원하는 방법으로 다시 만들 수도 있다.
유효성 검사가 채 끝나기도 전에 유저가 회원가입 버튼을 눌러버리면 어떻게 될까?
유효성 검사의 의미가 없다. submit 버튼을 눌러버리면 그대로 전송이 되기 때문에.
그러면 우리는 유효성 검사가 끝날 때까지 submit 버튼을 비활성화 시킬 필요가 있다.
그럴때 사용하는 속성이 button 태그의 disabled이다.
disabled에 true를 넣으면 비활성화가 되고, false를 넣으면 활성화가 된다.
<button
className={
isEmail && isPswd && isCheckPswd
? "border-2 border-black w-[100px] md:w-[200px] md:text-xl"
: "border-2 border-black bg-black text-white w-[100px] md:w-[200px] md:text-xl"
}
type="submit"
disabled={!(isEmail && isPswd && isCheckPswd)}
>
회원가입
</button>
아까 봤던 코드에서 setIsEmail이라는 setState를 볼 수 있다.
이는 유효성 검사가 통과될 때만 true의 값을 가진다.
이를 활용해서 disabled에 위와 같은 처리를 했다.
이메일, 비밀번호, 비밀번호 확인에서 모두 유효성 검사가 true가 되어야지만 disabled가 false가 되고, 유저는 본인이 작성한 정보를 submit 가능한 상태가 된다.