双因素认证
Pier 支持可选的 TOTP(基于时间的一次性密码)双因素认证,兼容任何身份验证器应用 —— Google Authenticator、Aegis、1Password 等。启用后,登录会增加第二步:在输入密码之后,你需要提供一个 6 位数字代码或一个一次性恢复码。
2FA 由每位用户在账户区域中自行注册。它不会改变会话的工作方式 —— 一旦你通过了第二重验证,你将获得与仅密码登录相同的不透明 Cookie 会话。
注册过程是两次调用的往返,这样在你证明能够生成有效代码之前,密钥绝不会被存储。
- 开始设置 ——
POST /api/v1/account/2fa/setup。Pier 返回一个全新的 base32secret、一个otpauth_url、一个内联的qr_svg,以及 10 个一次性恢复码。此时尚未持久化任何内容。 - 扫描二维码(或手动输入密钥)到你的身份验证器应用中。显示的发行方为
Pier。 - 保存你的恢复码。 它们只会显示一次。每个恢复码形如
XXXX-XXXX-XXXX,且仅能使用一次。 - 验证 ——
POST /api/v1/account/2fa/verify,提交secret、当前的 6 位code以及恢复码哈希值。若代码正确,Pier 会加密该密钥(AES-256-GCM,与你的环境变量使用同一密钥)并提交。若代码错误,则 2FA 保持关闭。
TOTP 代码以 ±1 步(±30 秒)的时间窗口进行验证,因此可以容忍手机上的微小时钟漂移。
你可以随时使用 GET /api/v1/account/2fa 重新查看注册状态,它会报告 enabled、enabled_at 和 recovery_codes_remaining。
启用 2FA 后的登录流程
Section titled “启用 2FA 后的登录流程”启用 2FA 后,登录变为两个步骤:
| 步骤 | 端点 | 你发送 | 你收到 |
|---|---|---|---|
| 1 | POST /api/v1/auth/login | 用户名 + 密码 | requires_2fa: true 和一个短期有效的 partial_token |
| 2 | POST /api/v1/auth/login/2fa | partial_token + code | 会话 Cookie |
partial_token 不是会话 —— 它仅证明你通过了密码步骤。它是一个保存在内存中的一次性令牌,5 分钟后过期,并与你的 IP 绑定。如果在此期间 pier-core 重启,请重新输入密码。
在第二步中,code 字段既接受你当前的 TOTP 代码,也接受你的某个恢复码。恢复码在使用时会被消耗(移除),因此它绝不会生效两次。
两个登录端点都进行了速率限制,以减缓针对 6 位数字代码的暴力破解尝试。
恢复码是你在丢失身份验证器设备时的备用手段。
- 注册时生成 10 个;仅存储它们的哈希值。
- 输入时不区分大小写和连字符(
abcd-EFGH-1234等同于ABCDEFGH1234)。 - 每个均为一次性使用。当
recovery_codes_remaining降至零时,请禁用并重新注册 2FA 以获取一组新的恢复码。
禁用 2FA
Section titled “禁用 2FA”POST /api/v1/account/2fa/disable 会关闭 2FA,但它要求在请求体中提供有效的当前 TOTP 代码或一个恢复码。这可以防止劫持了活动会话的人在你不知情的情况下悄悄削弱你的账户安全。成功后,密钥和恢复码都会被清除。
要轮换你的密钥(例如更换新手机后),请禁用 2FA 并重新注册 —— 当 2FA 仍处于启用状态时,Pier 会拒绝重新签发密钥。