Files
Genarrative/docs/technical/AUTH_REFRESH_SESSION_PERSISTENCE_HOTFIX_2026-04-24.md
kdletters cbc27bad4a
Some checks failed
CI / verify (push) Has been cancelled
init with react+axum+spacetimedb
2026-04-26 18:06:23 +08:00

3.0 KiB
Raw Permalink Blame History

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/refreshlogoutsessions 语义不变。

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_accountauth_identityrefresh_session 表及 reducer 全部落地后,替换策略如下:

  1. 保留 module-auth 用例语义。
  2. 把当前快照仓储替换为 SpacetimeDB 仓储适配器。
  3. 启动时可提供一次性导入脚本,把 JSON 快照导入 SpacetimeDB 表。
  4. 导入完成后禁用 GENARRATIVE_AUTH_STORE_PATH 快照写入。