docs: clarify supabase frontend access strategy

This commit is contained in:
Codex
2026-06-28 20:45:09 +08:00
parent 747d179e38
commit 22083db8ff
6 changed files with 212 additions and 8 deletions

View File

@@ -24,6 +24,7 @@
- `docs/refactor/frontend-handoff-index.md`:交给前端同事的阅读入口和当前可开工范围。
- `docs/refactor/backend-capability-status.md`:后端已覆盖、迁移期、待补齐能力盘点。
- `docs/refactor/legacy-feature-gap-matrix.md`:对照旧题库功能的新后端差距矩阵。
- `docs/refactor/supabase-frontend-access-strategy.md`Supabase 官方推荐能力与本项目业务 API 边界。
- `docs/refactor/taro-frontend-integration.md`Taro/H5/小程序启动、请求封装、页面/API 映射。
- `docs/refactor/multitenant-auth-security-contract.md`:多租户隔离、鉴权、权限和资源安全红线。

View File

@@ -12,11 +12,13 @@
- 看哪些后端能力已经能联调,哪些只是迁移期可用。
3. `docs/refactor/legacy-feature-gap-matrix.md`
- 对照旧题库功能,确认哪些页面能按新 API 重做,哪些后端还要补。
4. `docs/refactor/taro-frontend-integration.md`
4. `docs/refactor/supabase-frontend-access-strategy.md`
- 明确 Taro 什么时候可以用 Supabase client什么时候必须走 `apps/api`
5. `docs/refactor/taro-frontend-integration.md`
- Taro 启动、租户解析、请求封装、页面/API 映射、跨端注意事项。
5. `docs/refactor/multitenant-auth-security-contract.md`
6. `docs/refactor/multitenant-auth-security-contract.md`
- 多租户、鉴权、权限、资源签名和生产安全红线。
6. `docs/refactor/content-import-contract.md`
7. `docs/refactor/content-import-contract.md`
- 后台内容导入、题目 JSON、单词、知识手册的后端校验契约。
## 当前可进入的前端工作
@@ -29,11 +31,13 @@
- `question_collections`
- `practice_blueprints`
- 可以接入迁移期短信登录和 `tk_` session用于本地/内网联调。
- H5 可以优先验证 `@supabase/supabase-js` 管理 Auth session微信小程序端先验证运行时兼容性业务数据默认仍走 `apps/api`
- 可以接入租户品牌、主题、功能开关和域名/小程序参数解析。
## 不能误认为已商用完成的部分
- 生产鉴权尚未完成:当前很多接口仍用 `x-tenant-id``x-user-id``x-platform-admin-key` 作为迁移期上下文。
- 不要把“Supabase 支持前端 Data API”误解为“本项目所有业务表都由 Taro 直写”订单、支付、权益、租户后台、导入、CRM、私有资源必须走后端。
- 真实短信、微信登录、QQ 登录、微信支付、支付宝支付 provider 还未正式接完。
- 对象存储已完成签名 provider但 PDF 预览、防盗链、视频水印、上传后校验还要补。
- 大批量 Excel/CSV、分数线、视频导入和异步 worker 还未完成。
@@ -45,4 +49,3 @@
- 每个页面先接后端已有接口;缺接口时把页面期望的字段写到 issue/TODO再由后端补聚合接口。
- 权限判断以后端结果为准,前端只做菜单和按钮可见性优化。
- 旧项目只作为样式、交互和字段含义参考;长期数据模型以新 API 为准。

View File

@@ -2,7 +2,7 @@
更新时间2026-06-28
这个系统后续要卖给同行作为题库 SaaS因此租户隔离、鉴权、资源权限和审计是商用红线。前端可以先按迁移期接口联调但正式上云验收前必须完成本文件的 P0 项。
这个系统后续要卖给同行作为题库 SaaS因此租户隔离、鉴权、资源权限和审计是商用红线。前端可以先按迁移期接口联调也可以按 Supabase 官方推荐使用 publishable key + RLS 的客户端能力管理 Auth/session但正式上云验收前必须完成本文件的 P0 项。
## 安全边界
@@ -27,6 +27,8 @@
这些只允许用于本地开发和内网联调,不允许作为正式云端验收方案。
Supabase 官方允许前端用 Data API 访问数据,但前提是 RLS、最小 grant 和 JWT 权限模型都正确。本项目的核心业务表默认不开放给 Taro 直写;任何新增直连表都必须先通过 RLS、跨租户、权限和性能评审。
## P0正式云端测试前必须完成
1. 正式用户鉴权
@@ -69,6 +71,7 @@
## 前端必须遵守
- 不信任本地缓存里的 tenantId/userId 作为安全依据。
- 前端只能使用 Supabase publishable key不能出现 secret key 或 service role key。
- 不在页面里保存或展示任何商户密钥、短信密钥、OAuth secret。
- 不在前端硬编码对象存储 bucket、私有资源路径、商户号。
- 不在前端自行开通会员权益;必须通过订单/支付/激活码后端流程。
@@ -153,4 +156,3 @@ provider event id 幂等
- 激活码并发兑换只能成功一次。
- 对象存储签名 URL 有短 TTL。
- 后台关键操作写入 audit log。

View File

@@ -0,0 +1,161 @@
# Supabase 前端访问策略
更新时间2026-06-28
这份文档用于回答一个关键架构问题Taro/H5/小程序前端到底应该直接调用 Supabase还是调用我们自己的 `apps/api` 后端?
结论采用“Supabase Auth/JWT + 业务 API 优先 + 有边界的 Supabase Client 直连”的混合架构。
## 官方依据
Supabase 官方文档的核心原则:
- 前端可以使用 Supabase client/Data API 访问数据,但前提是启用 RLS并且只授予最小权限。
- https://supabase.com/docs/guides/database/secure-data
- https://supabase.com/docs/guides/database/postgres/row-level-security
- 前端应使用 publishable keypublishable key 可以暴露,但必须配合 RLS 和最小权限。
- https://supabase.com/docs/guides/database/secure-data
- https://supabase.com/docs/guides/getting-started/api-keys
- secret key / service role key 永远不能暴露在前端,因为它们会绕过 RLS。
- https://supabase.com/docs/guides/getting-started/api-keys
- 复杂服务端逻辑、第三方 API、webhook、密钥和数据库连接应放在服务端例如 Edge Functions、worker 或自有后端。
- https://supabase.com/docs/guides/functions
- Supabase Auth 使用 JWTJWT 可以和 RLS、服务端鉴权结合。
- https://supabase.com/docs/guides/auth
- https://supabase.com/docs/guides/auth/jwts
## 对本项目的判断
我们的系统不是简单 CRUD 应用,而是面向同行销售的题库 SaaS
- 多租户隔离。
- 平台超级管理员和租户管理员双后台。
- 租户内自定义角色、运营、教师、销售、代理、学生。
- 订单、支付、激活码、权益、视频次数。
- 题库导入、内容审核、资源台账。
- 阿里云 OSS、腾讯 COS、Supabase Storage 混合对象存储。
- CRM 推送、销售首绑、分佣结算。
- 未来还要接微信/QQ 登录、微信/支付宝支付、AI 报告。
这些都包含复杂业务规则、密钥、幂等、审计和跨表事务。因此不能让 Taro 前端直接写业务表来替代后端。
## 推荐架构
```text
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 表。
## 推荐前端环境变量
只允许出现在前端构建中的变量:
```text
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
```
禁止出现在前端:
```text
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 请求目标形态
当前迁移期:
```text
Authorization: Bearer <tk_session>
x-tenant-id: <tenantId>
x-user-id: <userId>
```
生产目标:
```text
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。

View File

@@ -2,7 +2,7 @@
更新时间2026-06-28
目标:用一套 Taro 工程同时服务微信小程序和 H5 Web 题库,统一调用 `apps/api`,并支持多租户、品牌主题、地区题库、会员权益、销售追踪和对象存储资源。
目标:用一套 Taro 工程同时服务微信小程序和 H5 Web 题库,并采用“Supabase Auth/JWT + `apps/api` 业务 API 优先”的混合架构,支持多租户、品牌主题、地区题库、会员权益、销售追踪和对象存储资源。
建议新建:
@@ -37,6 +37,22 @@ F:\project\参考\旧题库项目\src
## 请求封装
本项目不采用“前端直接写 Supabase 表替代后端”的模式。Supabase 官方允许前端在 RLS 和最小权限下使用 Data API但本系统的订单、支付、权益、租户后台、内容导入、CRM、对象存储签名等都需要服务端事务、密钥、审计和幂等所以业务数据默认调用 `apps/api`
前端可以使用 Supabase client 的范围:
- H5 Auth session/JWT。
- 小程序端在兼容性验证通过后的 Auth session/JWT。
- 低风险公开只读数据,且必须已经有 RLS、grant、跨租户测试。
- Realtime 非敏感通知。
前端必须调用 `apps/api` 的范围:
- 题库练习、答题、错题、收藏。
- 订单、支付、激活码、优惠券、权益。
- 私有 PDF、资料、视频、对象存储签名。
- 租户后台、平台后台、内容导入、CRM、销售/代理。
前端应封装一个统一 API client所有页面禁止直接散写 `Taro.request`
迁移期请求头:
@@ -50,11 +66,21 @@ x-user-id: <userId>
生产目标:
```text
Authorization: Bearer <jwt_or_session>
Authorization: Bearer <supabase_access_token_or_server_session>
```
生产后不应再由前端传 `x-user-id`。租户可以由可信 JWT claim、服务端 session、域名解析结果共同确定前端传入的租户参数只能作为路由/展示上下文,不能作为安全依据。
前端环境变量只允许包含:
```text
TARO_APP_API_BASE_URL
TARO_APP_SUPABASE_URL
TARO_APP_SUPABASE_PUBLISHABLE_KEY
```
禁止把 Supabase secret key、service role key、数据库连接串、对象存储密钥、支付私钥放进 Taro。
统一错误处理:
| HTTP | 前端动作 |
@@ -200,3 +226,13 @@ content_entries
9. 租户后台内容维护和导入。
10. 正式鉴权、真实支付、对象存储生产联调。
## Supabase Client 验证任务
前端 scaffold 后先做一个最小兼容性验证:
- H5`@supabase/supabase-js` 初始化、session 持久化、token refresh、logout。
- 微信小程序:验证自定义 storage/fetch/URL polyfill 是否稳定。
- API用 Supabase access token 调 `apps/api`,后端解析出可信用户。
- 安全:确认前端 bundle 中不存在 secret/service role/database/payment/storage 私钥。
如果微信小程序端 `supabase-js` 兼容性不稳定,小程序端改走 `apps/api/auth/*` 登录适配层H5 继续使用 Supabase client 管理 Auth。