Files
gongxue-base/docs/refactor/supabase-frontend-access-strategy.md

6.4 KiB
Raw Blame History

Supabase 前端访问策略

更新时间2026-06-28

这份文档用于回答一个关键架构问题Taro/H5/小程序前端到底应该直接调用 Supabase还是调用我们自己的 apps/api 后端?

结论采用“Supabase Auth/JWT + 业务 API 优先 + 有边界的 Supabase Client 直连”的混合架构。

官方依据

Supabase 官方文档的核心原则:

对本项目的判断

我们的系统不是简单 CRUD 应用,而是面向同行销售的题库 SaaS

  • 多租户隔离。
  • 平台超级管理员和租户管理员双后台。
  • 租户内自定义角色、运营、教师、销售、代理、学生。
  • 订单、支付、激活码、权益、视频次数。
  • 题库导入、内容审核、资源台账。
  • 阿里云 OSS、腾讯 COS、Supabase Storage 混合对象存储。
  • CRM 推送、销售首绑、分佣结算。
  • 未来还要接微信/QQ 登录、微信/支付宝支付、AI 报告。

这些都包含复杂业务规则、密钥、幂等、审计和跨表事务。因此不能让 Taro 前端直接写业务表来替代后端。

推荐架构

Taro/H5/小程序
  ├─ Supabase client
  │   ├─ Auth session/JWT
  │   ├─ 可选Realtime
  │   └─ 可选:严格 RLS 下的低风险只读数据
  │
  └─ apps/api 业务 API
      ├─ 校验 Supabase JWT/session
      ├─ 解析 tenant
      ├─ 校验角色和 permissions
      ├─ 执行业务事务
      ├─ 写审计日志
      ├─ 签发对象存储 URL
      └─ 调用支付/短信/微信/QQ/CRM/AI provider

apps/api 可以部署为我们自己的 Node.js API也可以在部分云原生场景下拆为 Supabase Edge Functions。对当前项目而言保留 apps/api 更适合复杂业务、国内 provider、自托管和后续 worker。

前端直连 Supabase 的适用范围

能力 是否建议前端直连 Supabase 说明
Supabase Auth session 建议 H5 可直接用 @supabase/supabase-js;小程序需先验证运行时兼容性
获取当前用户 JWT 建议 API 请求统一带 Authorization: Bearer <access_token>
低风险公开只读数据 可选 仅限 RLS、grant、索引都成熟后当前默认仍走 apps/api
Realtime 通知 可选 非敏感通知、学习状态刷新可考虑;后台敏感队列不建议前端订阅
Public Storage 公开资源 可选 真正公开的 Logo、主题图可直连 CDN/公开 bucket
私有资料/PDF/视频 不建议 必须通过 content_assets 权限校验和后端签名
学习记录/答题/错题/收藏 不建议 涉及权益、统计、审计、题目快照,应走 API
订单/支付/激活码/优惠券 禁止 必须走后端事务、验签和幂等
租户后台配置 禁止 涉及权限、密钥、审计
内容导入/题库维护 禁止 必须走 preview/import/job/issues 管线
平台超级后台 禁止 必须走平台管理员鉴权和审计

Taro 运行时建议

Taro 要同时支持 H5 和微信小程序。Supabase 官方 JavaScript client 是通用 JS SDK并提供 browser、React Native、自定义 fetch/storage 等配置方式,但微信小程序环境不等同于标准浏览器。

因此建议:

  1. H5 端优先使用 @supabase/supabase-js 管理 Auth session。
  2. 微信小程序端先做兼容性验证:
    • fetch 或 request adapter。
    • storage adapter。
    • URL polyfill。
    • token auto refresh。
  3. 如果小程序端 supabase-js 兼容成本高,则小程序只调用 apps/api/auth/*
    • 前端把微信 code 或手机号验证码发给后端。
    • 后端调用 Supabase Auth/Admin 或自有 session 逻辑换取可信 session。
    • 前端保存后端返回的 access token/session。
  4. 无论 H5 还是小程序,业务数据默认调用 apps/api,不直接写 Supabase 表。

推荐前端环境变量

只允许出现在前端构建中的变量:

TARO_APP_API_BASE_URL=https://api.example.com
TARO_APP_SUPABASE_URL=https://<project-ref>.supabase.co
TARO_APP_SUPABASE_PUBLISHABLE_KEY=sb_publishable_xxx

禁止出现在前端:

SUPABASE_SECRET_KEY
SUPABASE_SERVICE_ROLE_KEY
DATABASE_URL
ALIYUN_OSS_ACCESS_KEY_SECRET
TENCENT_COS_SECRET_KEY
WECHAT_PAY_PRIVATE_KEY
ALIPAY_APP_PRIVATE_KEY
AUTH_SESSION_SECRET
PLATFORM_ADMIN_API_KEY

API 请求目标形态

当前迁移期:

Authorization: Bearer <tk_session>
x-tenant-id: <tenantId>
x-user-id: <userId>

生产目标:

Authorization: Bearer <supabase_access_token_or_server_session>

生产时后端负责:

  • 验证 JWT。
  • 从 JWT/session 获取 userId。
  • 根据 host/tenantCode/JWT claims 解析 tenant。
  • 校验用户属于该租户。
  • 校验角色和权限。
  • 执行业务逻辑。

前端不再传 x-user-id,也不能靠传 tenantId 获得跨租户数据。

对后续 AI/开发者的硬性约束

  • 不要把 apps/api 删除或绕过。
  • 不要让 Taro 直接写订单、支付、权益、内容、租户配置、CRM、导入相关表。
  • 不要把 service role/secret key 放进 Taro。
  • 不要为了少写接口而放宽 RLS。
  • 新增前端直连 Supabase 表之前,必须先补:
    • 明确 RLS policy。
    • 最小 grant。
    • 跨租户测试。
    • 权限测试。
    • 性能索引。
  • 若某个功能需要密钥、跨表事务、webhook、审计、幂等或第三方 provider一律放到 apps/api 或 worker/Edge Function。