夏日幽灵 サマーゴースト (2021)
1772 字
9 分钟
Auth api设计详解
The Copenhagen Book
这本书是 Lucia 作者大佬 pilcrow 写的开源指南,围绕“如何把身份认证做对”展开。我按照书中章节脉络,结合在实际项目里踩过的坑,总结一份适合日常后端开发与产品协作的备查表。
以下内容覆盖:
- 身份模型(用户、身份、会话)如何拆分;
- 凭证存储与秘密管理;
- 注册/登录/忘记密码等基础流程;
- 多因素认证(MFA)、WebAuthn、第三方登录;
- 会话管理、切换设备、注销策略;
- 管理后台与自建 OAuth Provider;
- 审计日志、风控、隐私合规。
核心实体模型
The Copenhagen Book 把身份系统拆成三层,可避免“把所有逻辑塞进 user 表”:
| 实体 | 说明 | 常见字段 |
|---|---|---|
用户 (users) | 代表真实的个人或组织,提供业务上下文 | id, display_name, created_at, banned_at |
身份 (identities) | 每种登录方式的唯一标识 | id, user_id, provider_id, provider_user_id, created_at |
会话 (sessions) | 某次登录状态,可跨设备 | id, user_id, active_expires, idle_expires, user_agent, ip |
设计关键点:
- 用户可以拥有多个身份:邮箱密码、GitHub OAuth、手机号等。
- 身份与用户是 1
;会话与用户也是 1 。 - 会话应该存储 IP、 User-Agent、最近活动时间,便于风控与用户自助管理。
- 不要把密码、第三方 token、WebAuthn credential 混入用户表,分开存储才能实现更细的权限与轮换策略。
凭证存储与秘密管理
密码
- 使用
bcrypt、argon2id等现代算法,设置合理代价(如 argon2idtime_cost=3,memory=64MB)。 - 永远不要明文存储,也不要“自创盐”,库已经处理。
- 存储额外字段:
password_version(调整参数或算法时逐步迁移)、last_rotated_at。 - 登录成功后如果检测到 hash 版本过旧,后台静默升级(rehash-on-login)。
OTP 与重置码
- 一次性验证码/重置码使用
uuid或crypto.randomBytes生成,存储哈希值(sha256)。 - 记录
expires_at、consumed_at,用数据库唯一约束防止并发使用。 - 邮件/短信里不要包含用户 ID,用 token 换取身份。
JWT/Session Secret
- 密钥统一放在 Secret Manager(Vault、AWS Secrets Manager);禁用硬编码。
- 轮换策略:生成新密钥、让旧密钥在合理宽限期内仍可验证(kid 机制)。
- Server-side session 存数据库或 Redis 时,同步记录 IP/UA,异常时可以踢出。
注册流程最佳实践
- 前端校验:限制密码强度、邮箱格式,但不要过度暴露错误信息。
- 速率限制:邮箱注册/验证码接口需做 Rate Limit + Captcha。
- 邮箱验证:注册时生成 email verification token,允许账号未验证时有限操作(如仅能登录一次提醒验证)。
- 邀请制:提前创建 invitation 记录,关联
inviter_id、accepted_at,控制注册入口。 - 事务处理:创建用户、身份、发送验证邮件在事务中完成,失败时回滚。
登录流程
基础邮箱+密码
- 返回错误时统一提示“凭证错误”,避免区分“用户不存在”或“密码错误”。
- 支持 remember me:
idle_expires设置为 7-30 天,并通过 httpOnly + Secure Cookie 存储会话 ID。 - 登录成功写入审计日志(
login_success),包括设备指纹。
多因素认证(MFA)
- 支持 TOTP(Authenticator App)和备份代码(Backup Codes)。
- TOTP 种子加密存储(可用 KMS 包裹)。
- 绑定流程:显示二维码 → 输入 6 位验证码确认 →
is_primary_mfa标记。 - 登录流程:先验证主凭证,再要求 2FA;允许“信任设备”7-30 天,通过
mfa_remember_token标记。 - 恢复:备份代码一次性使用;客服通道需严格验证身份。
WebAuthn / Passkeys
- 存储 WebAuthn credential 时记录
credential_id,public_key,transports,sign_count。 - 对于 passkey,允许跨设备同步,不要绑定特定浏览器。
- WebAuthn 可作为无密码登录方式,也可作为 2FA。
第三方登录(OAuth/OIDC)
- 创建
oauth_providers表记录配置信息(client_id、scopes、redirect URI)。 - 将 provider 返回的
sub/id等唯一标识与identities表关联。 - 若用户首次使用第三方登录,需要流程:
- 找到与邮箱匹配的用户 → 提示合并或拒绝;
- 无匹配时创建新用户(可直接标记邮箱已验证)。
- 定期刷新 access_token/refresh_token;失效时告知用户重新授权。
会话管理
- 单点登录/多设备:允许多个活跃 session;提供“查看并注销其他设备”功能。
- 活跃检测:
active_expires表示 token 有效期,idle_expires表示最大不活跃时间。 - 注销:服务端删除 session 记录,删除 cookie/localStorage;对于 JWT 需维护 denylist 或缩短过期时间。
- Remembered Device:存储在
trusted_devices表,包含指纹、首次信任时间、最后使用时间。 - Session Fixation:登录成功后一定要 rotate session ID。
API 设计示例
POST /auth/register
POST /auth/login
POST /auth/logout
POST /auth/refresh
POST /auth/mfa/setup
POST /auth/mfa/verify
POST /auth/password/request-reset
POST /auth/password/reset
GET /auth/sessions
DELETE /auth/sessions/{sessionId}
返回格式建议统一:
{
"session": {
"id": "sess_123",
"expiresAt": "2025-05-01T00:00:00Z"
},
"user": {
"id": "user_456",
"displayName": "Alice",
"hasMfa": true
}
}
错误响应包含 code(内部追踪)与 message(给用户),必要时加 metadata:
{
"code": "AUTH_INVALID_TOTP",
"message": "验证码无效或已过期,请重试",
"metadata": {
"remainingAttempts": 3
}
}
管理后台与支持流程
- 管理后台应具备:搜索用户、查看身份信息、重置密码、禁用账号、强制注销等能力。
- 所有敏感操作(禁用、冻结资金)必须记录审计日志,含操作者 ID 与理由。
- 支持团队需要明确定义升级流程:例如社交账号被盗、设备遗失、申诉流程。
风险控制与检测
- 登录异常检测:同一账号在短时间内不同国家登录、IP 风险评分。
- 密码喷射(password spraying):统计不同邮箱的失败次数,整体限流。
- 设备指纹:可以使用指纹库或自定义 UA + 分辨率 + Canvas 指纹(注意隐私合规)。
- 风控触发时增加验证因素(Step-up Auth),例如要求验证码或 2FA。
审计与隐私
- 审计日志表存储:
event,user_id,session_id,actor_id,ip,user_agent,metadata,created_at。 - 遵守最小化原则:只收集必要数据,设定数据保留期限(GDPR、CCPA)。
- 提供数据导出与删除接口(Data Subject Request)。
- 避免在日志里记录敏感信息,如密码或完整 token。
常见坑位与应对
- 跨域 Cookie 失效:确保设置
SameSite=None且Secure,以及后台与前端域名一致。 - CSRF:推荐使用 SameSite Cookie + 双提交 Cookie 或 CSRF Token。
- 验证码滥用:引入滑块、人机验证服务,或对高危 IP 拦截。
- 缓存问题:包含授权信息的响应 header 应禁用 CDN 缓存。
- 时钟漂移:TOTP 校验容忍 ±30s;服务部署多地区需同步 NTP。
推荐工具与库
- Lucia:TypeScript 生态下的身份框架,书中示例基于它。
- NextAuth.js / Auth.js:前端友好的 Next.js 解决方案。
- Ory / Supabase Auth:托管身份平台,适合 MVP。
- FGA / CASL:做细粒度授权(Access Control)。
- Temporal / Q Stash:处理邮件发送、密码重置等异步任务。
进一步阅读
- The Copenhagen Book 原文
- OWASP ASVS:认证与会话安全条目。
- NIST 800-63B:数字身份指南(密码、MFA 建议)。
- WebAuthn Guide:无密码认证详解。
- Auth0 Blog:实战文章与攻防视角。


