beUI 회원가입 폼 복사 전에 확인할 검증 규칙과 비밀번호 정책
복사해 붙일 폼을 고르는 중이라면, beUI 회원가입 폼 컴포넌트는 코드보다 기본값을 먼저 봐야 합니다. 오류를 언제 띄울지, 비밀번호 강도를 무엇으로 잴지가 이미 박혀 있습니다.
컴포넌트 페이지와 레지스트리 JSON, NIST SP 800-63B 개정 4판 원문을 나란히 놓고 대조했습니다. 아래에서는 그 기본값이 무엇이고 어디부터가 쓰는 쪽 몫인지를 다룹니다.
설치 명령 한 줄에 UX 판단이 딸려 옵니다
beUI 회원가입 폼은 shadcn 레지스트리에 등록된 블록입니다. 설치는 bunx --bun shadcn add @beui/signup-form 한 줄이고, 컴포넌트 페이지에서 소스를 직접 복사해도 됩니다. 어느 쪽이든 코드는 프로젝트 안으로 들어와 그대로 남습니다. 받는 것은 파일 하나가 아니라 열 개가 넘는 묶음입니다.
의존성은 clsx, lucide-react, motion, tailwind-merge 네 개뿐입니다. registryDependencies 가 빈 배열이라 다른 UI 라이브러리를 끌어오지 않고 자체 부품으로 폼을 구성합니다. 쓰는 훅은 useState, useCallback, useMemo, useId 이고 여기에 useReducedMotion 과 useLayoutEffect 가 붙습니다. 모션 감소 설정을 읽는 훅이 들어가 있다는 점은 접근성 쪽에서 의미가 있습니다.
레지스트리 엔드포인트는 화면을 거치지 않고도
읽히므로, 페이지 설명 대신 그쪽 값을 먼저 확인했습니다. 아래는 2026년 8월 기준으로beui.dev/r/signup-form.json 에서 읽은 메타데이터를 줄인 것입니다. 파일 목록과 긴 설명문은 뺐고, author 필드에 함께 적힌 이메일 주소도 지웠습니다.
{
"name": "signup-form",
"type": "registry:block",
"title": "Sign Up Form",
"author": "Saurabh",
"dependencies": ["clsx", "lucide-react", "motion", "tailwind-merge"],
"registryDependencies": []
}
여기서 읽을 것은 두 줄입니다. registryDependencies 가 비어 있다는 것, 그리고 author 필드에 개인 이름이 적혀 있다는 것입니다. 이 블록이 누구 손에서 나왔는지는 페이지 소개문이 아니라 레지스트리 메타데이터가 알려 줍니다.
author 로 적힌 Saurabh 는 beUI 저장소를 운영하는 starc007 의 이름과 같습니다. 이 컴포넌트가 커뮤니티 PR 로 들어왔다는 이야기를 찾아봤지만 저장소와 레지스트리 어느 쪽에서도 확인하지 못했습니다. 저장소가 CONTRIBUTING.md 를 두고 외부 기여를 받는 것은 맞습니다.
오류 표시 시점은 blur 이후로 고정입니다
회원가입 폼의 검증 오류는 값이 바뀔 때마다 계산되지만, 화면에는 그 칸을 떠난 뒤에야 나타납니다. 이미 오류가 뜬 칸은 조건을 만족하는 순간 바로 지워집니다. 제출 버튼을 누르면 모든 칸이 한꺼번에 touched 로 표시되면서 남은 오류가 함께 드러납니다.
이 동작에는 이름이 있습니다. Mihael Konjević 가 2016년에 정리한 reward early, punish late 패턴입니다. 원문은 두 줄로 나눠 설명합니다. 유효한 상태였던 칸에 입력하는 중이면 입력이 끝난 뒤에 검증하고, 이미 무효였던 칸에 입력하는 중이면 입력하는 동안 검증한다는 것입니다.
인라인 검증 UX 원문reward early, punish late 라는 말이 어디서 나왔는지
대조한 자료들이 이 항목에서는 같은 값을 말합니다. Smashing Magazine 이 2022년에 낸 인라인 검증 정리도 늦은 검증이 대체로 낫다고 적고, 비어 있는 필수 칸은 제출 시점에만 지적하라고 권합니다. 같은 이름이 Vuelidate 이슈 같은 라이브러리 논의에서도 그대로 쓰입니다.
기본 검증기가 실제로 보는 항목은 다섯 개입니다.
- 이름: 빈 값 불가
- 이메일:
/^[^\s@]+@[^\s@]+\.[^\s@]+$/통과 - 비밀번호: 8자 이상
- 확인란: 비밀번호와 일치
- 약관: 동의 체크
다섯 항목 모두 브라우저에서만 도는 검사입니다. 검증 함수는 바깥에서 갈아 끼울 수 있게 열려 있어서, 이 목록은 출발점이지 최종 규칙이 아닙니다.
강도 점수는 길이가 정하고 문자 종류는 보너스입니다
passwordStrength 함수는 0에서 4 사이 점수를 냅니다. 점수를 가르는 주된 값은 길이이고, 문자 종류의 다양성은 조건을 채웠을 때만 1점을 더합니다. 8자에 못 미치면 다른 조건을 아무리 채워도 0점입니다.
점수가 어떻게 쌓이는지는 조건별로 나눠 보면 분명해집니다. 아래 값은 레지스트리에 실린 소스에서 읽은 것입니다.
| 조건 | 점수 |
|---|---|
| 8자 미만 | 0 |
| 8자 이상 | 1 |
| 12자 이상 | +1 |
| 16자 이상 | +1 |
| 소문자·대문자·숫자·기호 중 3종류 이상 | +1 |
| 상한 | 4 |
표에서 읽을 것은 문자 종류 항목이 마지막 줄에 한 번만 나온다는 점입니다. 특수문자를 하나 끼워 넣어도 짧은 비밀번호를 끌어올리지 못하고, 반대로 16자를 넘기면 종류를 섞지 않아도 상한 가까이 닿습니다.
화면에는 막대 네 개와 라벨이 붙습니다. 라벨은 Too short, Weak, Fair, Good, Strong 다섯 가지입니다. 어느 점수가 어느 라벨에 붙는지까지는 확인하지 못해 여기 적지 않았습니다.
컴포넌트 페이지에 붙은 코드 주석은 이 설계를 스스로 설명합니다. 길이 가중 점수이고, NIST SP 800-63B 가 구성 요건에 반대하며 길이를 지배적 요인으로 본다는 문장이 그대로 적혀 있습니다. 같은 주석은 이 값이 엔트로피 추정이 아니라 피드백용 휴리스틱이며 실제 서비스라면 서버 쪽 유출 목록 대조와 짝지으라고 덧붙입니다.
비밀번호 8자 최소값이 걸리는 조건
컴포넌트 주석은 NIST SP 800-63B 를 길이 가중치의 근거로 인용하지만, 같은 문서에는 기본 검증기의 8자 최소값과 나란히 놓기 어려운 대목이 있습니다. NIST 는 비밀번호가 단일 인증 수단일 때 최소 15자를 요구합니다.
NIST SP 800-63B 개정 4판 3.1.1.2 절은 두 값을 나눠 적습니다. 단일 요소 인증에 쓰이는 비밀번호는 최소 15자를 SHALL 로, 다중 요소 구성에서는 최소 8자를 SHALL 로 둡니다. 그러니 8자가 곧 규격 위반은 아닙니다. 두 번째 인증 수단이 없는 서비스라면 이 값부터 올려야 한다는 뜻입니다.
구성 규칙 쪽은 컴포넌트의 선택과 맞습니다. 같은 절이 문자 종류를 섞으라는 식의 구성 규칙을 부과하지 말라고 SHALL NOT 으로 적습니다. 개정 4판 변경점을 정리한 글도 같은 값을 말했고, 이 항목에서는 두 자료가 갈리지 않았습니다.
빠진 단계는 유출 목록 대조입니다. 같은 절은 새 비밀번호를 흔히 쓰이거나 유출된 값의 블록리스트와 비교하라고 SHALL 로 요구하는데, 기본 검증기에는 그 검사가 없습니다. 컴포넌트 쪽도 이를 감추지 않고 서버에서 붙이라고 주석에 적어 두었습니다. UI 부품이 정책까지 대신 정해 주지는 않는 경계입니다.
제출 상태 네 가지 중 error 복귀가 핵심입니다
beUI 회원가입 폼의 제출 상태는 idle, loading, success, error 네 가지로 나뉩니다. 상태 사이의 글자와 아이콘 전환은 StatefulButton 이 맡습니다. 직접 폼을 짤 때 가장 자주 빠지는 자리가 error 에서 다시 입력 가능한 상태로 돌아오는 경로인데, 이 구조는 그 상태를 처음부터 이름 붙여 두었습니다.
StatefulButton 은 별도 파일로 떨어져 있습니다. 레지스트리 파일 목록에서 button 디렉터리가 base, magnetic, stateful 로 나뉩니다. 글자가 바뀔 때 버튼 폭이 튀지 않도록 useLayoutEffect 로 텍스트 너비를 재고, useSpring 과 useMotionValue 는 magnetic 쪽 물리에 쓰입니다. 폼만 필요하고 자석 효과가 필요 없다면 이 파일들을 걷어내는 작업이 먼저입니다.
이메일 검사는 느슨하게 잡혀 있습니다. 정규식은 공백 없는 문자열과 골뱅이표, 점 하나 정도만 확인하는 수준입니다. 컴포넌트 페이지도 이를 의도적으로 관대한 패턴이라고 밝히면서 서버 쪽 검증을 권합니다. 화면에서 걸러 주는 것과 서버가 받아들이는 것은 별개입니다.
실무에서 더 중요한 것은 검증 함수 자체를 갈아 끼울 수 있다는 점입니다. 값은 제어형과 비제어형 양쪽으로 받고, 검증 함수는 바깥에서 주입할 수 있습니다. 기본값을 그대로 둘지 말지가 선택지로 남아 있다는 뜻입니다.
붙여 넣기 전에 정해야 할 값
이 폼을 그대로 쓸지 판단하는 기준은 인증 방식입니다. 비밀번호가 유일한 인증 수단이면 8자 최소값과 유출 목록 대조부터 손봐야 하고, 두 번째 요소가 있으면 기본값을 유지해도 무리가 없습니다. 점수와 라벨의 대응, 이 블록이 커뮤니티 기여로 들어왔는지 여부는 확인하지 못했으니 컴포넌트 페이지에서 직접 보는 편이 낫습니다.
첫 작업은 defaultValidate 를 열어 비밀번호 조건 한 줄을 서비스 정책 값으로 바꾸는 것입니다.
출처: beUI Sign Up Form 컴포넌트 페이지, beUI 레지스트리 JSON, NIST SP 800-63B 개정 4판, Mihael Konjević, 인라인 검증 UX, Smashing Magazine 인라인 검증 정리
