用途
登录表单(Login Form)是用户进行身份验证并获取受保护内容与功能访问权限的主要入口。它通常包含一个标识字段(邮箱或用户名)、一个密码字段和一个提交按钮,并常配有“记住我”“忘记密码”以及社交登录选项。设计良好的登录表单需要在安全性与可用性之间取得平衡:对合法用户尽量减少摩擦,同时防止未授权访问。
何时使用
使用登录表单来验证回访用户并授予对受保护资源的访问权限。常见场景包括:
- 需要在访问功能前进行用户身份验证的 Web 应用
- 用户登录后查看订单、愿望清单和已保存地址的电商站点
- 将功能置于用户账号之后的 SaaS 平台
- 需要身份才能参与的社区或社交平台
- 基于角色访问的管理后台和内部工具
何时避免
- 不需要身份验证的公开页面
- 受益于开放访问的只读内容(博客、文档)
- 身份验证会带来不必要摩擦的一次性交互
- 会话管理不便的自助终端或共享设备界面
实现流程
- 在复制示例前,先确认该模式与问题及约束条件相匹配。
- 从 references/pattern.md 中的解剖结构与示例入手,然后选择最小的可行变体。
- 在叠加视觉打磨之前,先应用无障碍、性能和交互护栏。
- 使用测试指引验证键盘、屏幕阅读器、响应式和失败场景下的行为。
无障碍护栏
应做 ✅
- 使用 for/id 配对将所有字段与 <label> 元素关联
- 使用 autocomplete="email" 和 autocomplete="current-password" 以支持浏览器自动填充
- 使用 role="alert" 显示错误,并通过 aria-describedby 将其与字段关联
- 用 aria-invalid="true" 标记无效字段
- 确保密码切换按钮在切换时更新其 aria-label
- 支持通过 Enter 键提交表单
不应做 ❌
- 不要用 placeholder 替代标签
- 不要在没有说明原因的情况下禁用提交按钮(应改用验证消息)
性能护栏
目标指标
- 表单渲染:完整登录表单 < 100ms
- 输入响应:按键到显示 < 50ms
- 验证反馈:内联验证 < 100ms
- 身份验证请求:感知 < 1000ms(立即显示加载状态)
- 成功后重定向:导航开始 < 200ms
优化策略
预取登录后目标页面:
<link rel="prefetch" href="/dashboard" />
常见错误
暴露账号是否存在
问题:诸如“该邮箱没有对应账号”或“密码错误”之类的错误消息会让攻击者能够枚举有效账号。
修复方法:使用通用消息:“邮箱或密码无效,请重试。”并对两种情况应用相同的响应时间。
没有速率限制反馈
问题:用户可以无休止地提交表单,却没有任何账号正在被锁定或受到速率限制的提示。
修复方法:在 3-5 次失败尝试后显示消息:“尝试次数过多。请等待 30 秒后再试。”并在服务端实现带指数退避的速率限制。
出错时清空字段
问题:登录失败时表单清空了邮箱字段。
修复方法:失败尝试后保留邮箱值。只清空密码字段,因为重新输入密码是安全最佳实践。
相关模式
- https://uxpatterns.dev/patterns/authentication/password-reset
- https://uxpatterns.dev/patterns/authentication/signup
- https://uxpatterns.dev/patterns/authentication/social-login
- https://uxpatterns.dev/patterns/authentication/two-factor
完整实现细节、示例和测试说明,请参见 references/pattern.md。
模式页面:https://uxpatterns.dev/patterns/authentication/login