Files
medical-mall/components/supadb/SESSION_RECOVERY.md
2026-02-02 18:20:22 +08:00

3.9 KiB
Raw Blame History

Supabase 会话恢复说明supa session recovery

  • 目的: 说明为什么刷新后 session / user 变为 null,以及我在项目中做了哪些修改来改善会话恢复。

  • 文件变更:

    • components/supadb/aksupainstance.uts: 统一 Supabase 实例导出,新增 supaReady 初始化流程。在初始化时尝试从持久化 tokenAkReq 存储)读取 access_token / refresh_token,将 refresh token 注入到 supa.session 并调用 supa.refreshSession() 以恢复会话;保留 ensureSupabaseReady() 作为兼容接口。
    • utils/store.uts: 将 import 改为 import supa, { supaReady },并在获取 session 前 await supaReady,确保恢复逻辑已经运行完毕。
    • utils/sapi.utspages/sense/senseDataService.uts 及若干页面文件: 替换对旧 ensureSupabaseReady 的调用,改为 await supaReady,并使用默认导出的 supa 实例。
  • 问题根本原因:

    1. 系统原先将会话信息保持在 AkSupa.session / AkSupa.user(内存)中,页面刷新或应用重启会清空内存,导致 supa.getSession() 返回 null
    2. 虽然 AkReq.setTokenaccess_token / refresh_token 持久化到 uni storageAkSupa 在启动时没有读取这些持久化 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_URLSUPA_KEY
    • refresh token 本身也是敏感凭证,应妥善保管;如需长期保持登录,建议使用 refresh 流程并合理设置过期与刷新策略。

如果你需要,我可以继续:

  • AkSupa 中实现“登录后持久化 session JSON”的补丁并在 signOut 时清理;
  • 或添加更详细的调试输出帮助定位某次具体恢复失败的 HTTP 请求和响应。

文件路径components/supadb/SESSION_RECOVERY.md