迁移后端认证与拆分 Spacetime 客户端
This commit is contained in:
@@ -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` 快照写入。
|
||||
|
||||
Reference in New Issue
Block a user