迁移后端认证与拆分 Spacetime 客户端

This commit is contained in:
2026-04-24 14:10:11 +08:00
parent ef53028be5
commit 4f369617c7
55 changed files with 9206 additions and 343 deletions

View File

@@ -0,0 +1,66 @@
# Auth refresh session 持久化热修方案
日期:`2026-04-24`
## 1. 背景
当前 Rust 鉴权链路已经具备 refresh cookie 自动续签能力access token 过期后,前端会调用 `POST /api/auth/refresh`,后端轮换 refresh token 并返回新的 access token。
`module-auth` 当前仍使用进程内 `InMemoryAuthStore` 保存账号与 refresh session。只要 `server-rs` 在 access token 生命周期内发生重启,浏览器侧 HttpOnly cookie 仍然存在,服务端却找不到对应账号与 session最终表现为约 `JWT_EXPIRES_IN` 后需要重新登录。
## 2. 本次目标
本次先落一个低风险持久化闭环,解决“后端重启导致 2 小时后必须重新登录”的线上体验问题:
1. 为当前 `InMemoryAuthStore` 增加 UTF-8 JSON 快照文件。
2. 在账号、手机号索引、微信身份、refresh session 发生变更后自动保存快照。
3. `api-server` 启动时从配置路径恢复快照。
4. 保持现有 `/api/auth/refresh``logout``sessions` 语义不变。
## 3. 非目标
本次不把完整认证域一次性迁入 SpacetimeDB 表,原因是 refresh session 独立持久化不足以解决问题refresh 成功后还需要按 `user_id` 读取账号快照重新签发 access token因此账号主数据也必须同源恢复。
SpacetimeDB 正式表接管仍按以下既有文档继续推进:
1. `docs/technical/SPACETIMEDB_AUTH_USER_ACCOUNT_TABLE_DESIGN_2026-04-21.md`
2. `docs/technical/SPACETIMEDB_AUTH_IDENTITY_TABLE_DESIGN_2026-04-21.md`
3. `docs/technical/SPACETIMEDB_REFRESH_SESSION_TABLE_DESIGN_2026-04-21.md`
## 4. 配置
新增环境变量:
| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `GENARRATIVE_AUTH_STORE_PATH` | `server-rs/.data/auth-store.json` | 当前 Rust 鉴权快照文件路径。相对路径按进程工作目录解析。 |
## 5. 数据边界
快照文件保存当前 Rust 鉴权服务已经在内存中维护的最小真相:
1. `next_user_id`
2. `users_by_username`
3. `phone_to_user_id`
4. `sessions_by_id`
5. `session_id_by_refresh_token_hash`
6. `wechat_identity_by_provider_uid`
7. `user_id_by_provider_union_id`
短信验证码和微信 OAuth state 不持久化,原因是它们是短生命周期挑战数据,重启后失效是可接受行为。
## 6. 安全约束
1. refresh token 原文仍只存在浏览器 HttpOnly cookie快照只保存 `sha256(refresh_token)`
2. 快照包含 `password_hash`、手机号映射和 refresh token hash部署时必须放在服务端私有目录不允许暴露到静态资源目录。
3. 快照写入必须使用 UTF-8并通过临时文件原子替换降低写坏风险。
## 7. 后续 SpacetimeDB 接管点
`user_account``auth_identity``refresh_session` 表及 reducer 全部落地后,替换策略如下:
1. 保留 `module-auth` 用例语义。
2. 把当前快照仓储替换为 SpacetimeDB 仓储适配器。
3. 启动时可提供一次性导入脚本,把 JSON 快照导入 SpacetimeDB 表。
4. 导入完成后禁用 `GENARRATIVE_AUTH_STORE_PATH` 快照写入。