**Supabase 会话恢复说明(supa session recovery)** - **目的**: 说明为什么刷新后 `session` / `user` 变为 `null`,以及我在项目中做了哪些修改来改善会话恢复。 - **文件变更**: - **`components/supadb/aksupainstance.uts`**: 统一 Supabase 实例导出,新增 `supaReady` 初始化流程。在初始化时尝试从持久化 token(`AkReq` 存储)读取 `access_token` / `refresh_token`,将 refresh token 注入到 `supa.session` 并调用 `supa.refreshSession()` 以恢复会话;保留 `ensureSupabaseReady()` 作为兼容接口。 - **`utils/store.uts`**: 将 `import` 改为 `import supa, { supaReady }`,并在获取 session 前 `await supaReady`,确保恢复逻辑已经运行完毕。 - **`utils/sapi.uts`**、**`pages/sense/senseDataService.uts`** 及若干页面文件: 替换对旧 `ensureSupabaseReady` 的调用,改为 `await supaReady`,并使用默认导出的 `supa` 实例。 - **问题根本原因**: 1. 系统原先将会话信息保持在 `AkSupa.session` / `AkSupa.user`(内存)中,页面刷新或应用重启会清空内存,导致 `supa.getSession()` 返回 `null`。 2. 虽然 `AkReq.setToken` 将 `access_token` / `refresh_token` 持久化到 `uni` storage,但 `AkSupa` 在启动时没有读取这些持久化 token 并执行恢复/刷新流程(或未将 refresh token 注入到 `AkSupa`),因此无法重建会话。 3. 若 refresh token 过期或没有被正确持久化,也会导致恢复失败。 - **我做的修改说明(要点)**: - 在 `aksupainstance.uts` 添加 `supaReady`:这是一个 Promise,模块初始化时会尝试读取 `AkReq.getRefreshToken()` / `AkReq.getToken()`;若找到 refresh token,则把其临时赋到 `supa.session`,再调用 `supa.refreshSession()` 以更新内存中的 session 和 user。 - 在所有依赖会话的模块中,在执行数据库请求前 `await supaReady`,确保恢复尝试已完成,避免 race condition(页面刷新后立即调用 supa API 导致 401/空 session)。 - 保留向后兼容接口 `ensureSupabaseReady()`(内部直接返回 `supaReady`)。 - **如何验证(开发环境)**: 1. 登录并确认本地存储中有 token(通过控制台或在 uni 环境运行): - `uni.getStorageSync('akreq_access_token')` - `uni.getStorageSync('akreq_refresh_token')` 2. 刷新页面或重启应用,打开控制台查找初始化日志或错误(`Supabase instance init failed` 等)。 3. 在页面中(例如 `pages/mall/delivery/index.uvue`)查看已有的调试输出:search `supa session=` 的 console 日志,应显示非 null session(若 refresh 成功)。 4. 若恢复失败,请检查后端 refresh 接口是否返回 200,以及 refresh token 是否已过期。 - **后续建议(可选)**: - 在 `AkSupa.signIn` / `refreshSession` 成功时,将完整 session(或至少 `refresh_token`)写入 `uni.setStorageSync`(持久化),并在 `signOut` 时清除,这样可以进一步减少恢复失败的情况。 - 将 `supa.session` 的 JSON 快照也写入 storage(作为额外冗余),并在 init 时尝试直接恢复(注意安全和敏感信息保护)。 - 增加更详细的日志(成功/失败原因),并在 UI 层对“登录过期”做更友好的提示或自动跳转到登录页。 - **注意事项**: - 切勿在代码中硬编码匿名 key 或生产密钥;请在 `ak/config.uts` 中正确配置 `SUPA_URL` 和 `SUPA_KEY`。 - refresh token 本身也是敏感凭证,应妥善保管;如需长期保持登录,建议使用 refresh 流程并合理设置过期与刷新策略。 如果你需要,我可以继续: - 在 `AkSupa` 中实现“登录后持久化 session JSON”的补丁,并在 `signOut` 时清理; - 或添加更详细的调试输出帮助定位某次具体恢复失败的 HTTP 请求和响应。 文件路径:components/supadb/SESSION_RECOVERY.md