# 架构、信任边界与流程图

以下图形是仓库内静态 SVG，随单二进制嵌入；不访问 CDN 或在线渲染。可点击原图后保存。图中箭头表示请求或结果交付，不代表客户端可以绕过鉴权；重试仅适用于标出的安全分支。

## 三种接入方式

![三种接入方式](/docs/diagrams/architecture.svg)

[查看 / 下载 SVG 原图](/docs/diagrams/architecture.svg)

1. 统一登录：浏览器导航到平台，平台 Cookie 仅属平台。
2. 授权码回调 → Secret + PKCE 换码 → 本地业务会话。
3. 自定义 Web：同源 CSRF POST 创建，verifier/state/nonce 留后端。
4. 密码 / 短信 / 扫码直接认证；短期 WebAuth 凭据留内存。
5. 一次性 code 同源交付；长期 Token 只存产品后端。
6. Native：原生 HTTP + PKCE；无 Secret、不依赖浏览器 Cookie。

## 官网不跳页认证时序

![官网不跳页认证时序](/docs/diagrams/web-sequence.svg)

[查看 / 下载 SVG 原图](/docs/diagrams/web-sequence.svg)

1. ① 当前业务会话 + CSRF 创建事务。
2. ② Web Basic、精确 Origin、回调、state、nonce、S256。
3. ③ 五分钟凭据；不返回 Web Secret / verifier。
4. ④ WebAuth + Origin：二维码 / 短信 / 密码；Cookie omit。
5. ⑤ ready 后同意协议 → 一次性 code（60 秒）。
6. ⑥ 同源 POST code；后端校验原会话、state、issuer、回调。
7. ⑦ Basic + verifier 换码、RS256/JWKS + nonce + UserInfo。
8. ⑧ 业务会话 Cookie；长期 Token 不返回浏览器。

## 桌面原生认证时序

![桌面原生认证时序](/docs/diagrams/native-sequence.svg)

[查看 / 下载 SVG 原图](/docs/diagrams/native-sequence.svg)

1. ① 随机 verifier/state/nonce；Native Client 创建五分钟事务。
2. ② 原生 HTTP 下载二维码 / 提交短信 / 密码。
3. ③ ready / phone_required；新身份绑定手机号。
4. ④ 当前协议 + complete；领取一次性授权码。
5. ⑤ 无 Secret；S256 verifier 换 Token。
6. ⑥ 校验签名、issuer、aud、exp、nonce；Token 存系统凭据库。
7. ⑦ 产品校验用户身份后映射 stable sub；错误不自动重放。

## 公众号关注与扫码

![公众号关注与扫码](/docs/diagrams/wechat.svg)

[查看 / 下载 SVG 原图](/docs/diagrams/wechat.svg)

1. 创建随机场景与事务；二维码有效五分钟。
2. 申请公众号临时带参数二维码。
3. 未关注：扫码并关注；已关注：扫码。
4. subscribe / SCAN：签名 + AES 解密、一次性事件处理。
5. UnionID 已绑定 → ready；新身份 → phone_required。
6. 短信确认手机号；当前协议；原事务完成。
7. 身份冲突：拒绝自动合并；过期/取消/重放：拒绝。

## 短信挑战与结果未知

![短信挑战与结果未知](/docs/diagrams/sms-unknown.svg)

[查看 / 下载 SVG 原图](/docs/diagrams/sms-unknown.svg)

1. 提交 E.164 手机号；凭据绑定用途与事务。
2. 原子限流 + 挑战预留；随机源失败直接拒绝。
3. 发送一次，不对未知结果自动重试。
4. 明确受理 → 激活挑战；明确失败 → 回滚预留。
5. 超时 / 连接中断 → unknown；挑战不激活。
6. 返回 202 unknown，等待 >=60 秒后由用户手动决定。
7. 短信校验只消费本事务激活挑战；Redis 故障返回 503。

## 改密与撤销的事务边界

![改密与撤销的事务边界](/docs/diagrams/password-revoke.svg)

[查看 / 下载 SVG 原图](/docs/diagrams/password-revoke.svg)

1. reset 无会话；set 绑定该 Client 的有效 Access Token。
2. 本事务短信验证；set 只能验证账号当前手机号。
3. 复核账号状态、手机号、认证版本和源 Token。
4. 提交新密码：统一策略 + Argon2id。
5. 同一提交：密码 + 中央 Session/Token 撤销 + 旧证明取消。
6. 同一提交：user.sessions_revoked Outbox。
7. 完成后重新登录；不发授权码 / 新会话；超时不自动再提交。
8. 产品消费签名事件，幂等撤销本地业务会话。

## 授权码和刷新重放防护

![授权码和刷新重放防护](/docs/diagrams/token-replay.svg)

[查看 / 下载 SVG 原图](/docs/diagrams/token-replay.svg)

1. 一次性 code + PKCE（Web 另加 Basic）。
2. 授权码原子消费；检查 Client、回调、授权请求未撤销。
3. 返回 ID / Access / Refresh；校验签名和 nonce。
4. 串行刷新；旧 Refresh 一经使用不得再用。
5. 轮换新 Refresh；撤销原关联 Access。
6. 旧 code 重放 → 拒绝；旧 Refresh 重放 → 撤销 family。
7. 网络结果未知：停止自动重放，重新登录恢复。

## 认证短信与业务短信

![认证短信与业务短信](/docs/diagrams/sms-boundary.svg)

[查看 / 下载 SVG 原图](/docs/diagrams/sms-boundary.svg)

1. WebAuth / Native：平台生成和验证 OTP；不返回验证码。
2. Service Token sms:send：调用已授权业务模板。
3. 业务短信只返回受理/未知状态；不是用户认证证明。
4. 认证成功只交付一次性登录 code，不给服务 Scope。
5. 业务查询使用 sms:read；模板和额度按产品隔离。
6. 浏览器绝不持 Service Secret / 服务 Access Token。

## 支付回调与退款信任边界

![支付回调与退款信任边界](/docs/diagrams/payments.svg)

[查看 / 下载 SVG 原图](/docs/diagrams/payments.svg)

1. 产品服务端定价，整数分 + 幂等 Key 创建。
2. 随机收银台 URL；浏览器不能改金额。
3. 创建渠道单；超时未知由 Worker 查询。
4. 签名回调 + 解密 + 商户/金额/币种核验。
5. 行锁幂等：paid + Outbox 同一事务。
6. 签名 payment.succeeded；产品事件幂等交付权益。
7. 退款：幂等 Key、累计金额；超阈值待人工审批。
8. 退款回调 / 查询确认；对账差异不自动改资金状态。

## Webhook 至少一次投递

![Webhook 至少一次投递](/docs/diagrams/webhook.svg)

[查看 / 下载 SVG 原图](/docs/diagrams/webhook.svg)

1. 业务状态与事件原子写入；事件含稳定 sub，不含完整手机号。
2. 事件 ID、时间戳、HMAC 签名；TLS 固定端点。
3. 校验签名与时效；事件 ID 唯一约束。
4. 业务处理和已消费标记同一事务。
5. 成功返回 2xx；重复事件也幂等成功。
6. 超时 / 非成功：指数退避；不把超时当业务未发生。
7. 重投同一事件 ID；产品不得重复交付权益。
