身份认证
配置 Better Auth、邮箱验证、OAuth、两步验证、API Keys 和管理员边界。
认证由哪些模块负责
packages/auth/src/index.ts 创建 Better Auth 实例,接入 D1、邮件、API Keys、双因素与管理员插件。应用的 /api/auth/* 转交 Better Auth;页面入口位于 apps/web/src/routes/$.tsx,服务端业务权限在 apps/web/src/server/api.ts 再次执行。
系统区分未登录、普通用户、管理员及被封禁或邮箱未验证的账号。不要把角色字段从浏览器请求直接写入数据库,也不要仅用侧栏是否显示后台来判断权限。
默认验证码登录
访问 /auth/login,输入邮箱发送六位验证码,再提交最新验证码。现有账号登录,新地址可创建账号;本地在 /dev/mail 查看邮件,生产由真实邮箱收取。页面保留重发、返回修改邮箱与两步验证跳转。需要密码时选择“使用密码”进入 /auth/password。
对应 Better Auth API 为 /api/auth/email-otp/send-verification-otp(type 为 sign-in)与 /api/auth/sign-in/email-otp。不要自行保存验证码或把验证改成客户端判断。
密码注册、验证和重置
- 访问
/auth/register提交邮箱与密码。 - 按邮件中的链接完成邮箱验证;当前配置要求验证邮箱,并允许验证后自动登录。
- 使用
/auth/password密码登录,检查工作台能加载当前用户数据。 - 忘记密码时使用
/auth/forgot-password,通过邮件进入/auth/reset-password。
本地邮件在 /dev/mail 查看;该开发收件箱不应在生产可用。重置链接或验证码属于一次性凭据,不记录到公开日志、截图或问题描述中。生产须先完成真实邮件验收,不能把本地收件箱成功当作投递成功。
OAuth 与 Turnstile
在本地 .dev.vars 或生产根目录 .env 配置对应变量对:
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
GITHUB_CLIENT_ID=your-client-id
GITHUB_CLIENT_SECRET=your-client-secret
TURNSTILE_SITE_KEY=your-site-key
TURNSTILE_SECRET=your-secret-keyGoogle 回调为 https://your-domain.com/api/auth/callback/google,GitHub 对应 /github。本地使用准确的 localhost origin 单独登记。Better Auth 的 trustedOrigins 来自 APP_URL;中文页面也不改变 API 回调路径。
前端从 /api/public/auth 获取可公开配置。Provider 的变量不完整时,应修复配置,不要强制显示一个无法工作的登录按钮。Turnstile 还需要正确的域名白名单,Secret 永不进入浏览器。
设置页的会话与两步验证
/app/settings 提供资料、会话、API Keys 和双因素入口。资料更新使用 Better Auth update-user;会话列表及撤销、API Key 创建及删除也调用其专有 API。
启用 TOTP 后,应完成验证码验证并保存恢复材料,再验证下一次登录会进入 /auth/verify-two-factor。测试撤销某个会话后,该会话不能继续访问受保护数据。敏感操作失败应显示具体错误并允许重试,不能只把按钮切成成功状态。
API Key 的权限范围
API Key 通过 x-api-key 请求头传递,当前只用于文件列表、上传、下载和删除。服务端仍检查 Key 所属用户是否已验证且未封禁,并按 userId 限定文件归属。
创建时保存显示的完整 Key;列表和日志不应重新暴露 Secret。不要把文件 Key 用于聊天、支付或管理员 API,也不要将部署用 Cloudflare Token 当作文件 Key。
管理员与数据隔离
生产配置 ADMIN_EMAIL 后,匹配账号仍需自己注册并验证邮箱;生产不会使用 local_admin seed。后台页面路径是 /app/admin。
管理员接口覆盖用户、订单、任务、Webhook、审计、退款及死信。角色修改只允许 admin/user,并禁止修改自己的角色。积分发放使用正整数金额和 UUID requestId 保持幂等;退款、重放等操作保留服务端限制与确认对象信息。
验收清单与排障
- 未登录直接访问工作台及后台 API 应失败;普通用户不能访问管理员数据。
- 用户 A 不能读写用户 B 的文件、订单、任务或会话。
- 验证 OAuth、邮箱确认、重置、TOTP、会话撤销和 Key 删除后的实际请求。
- 登录循环:核对 APP_URL、cookie origin、域名协议及认证密钥是否改变。
- 收不到验证邮件:按 邮件指南 区分本地捕获和真实投递。