Next.js + Supabase 实战
Next.js 和 Supabase 的组合之所以受欢迎,不只是因为“上手快”,而是因为它把认证、数据库、实时和对象存储放进了同一个开发闭环。
但真正上线时,大家最容易踩的不是 API 用法,而是权限边界:
- 哪些请求该走 server。
- 哪些查询可以放 client。
- RLS 到底保护了没有。
- 服务角色 key 有没有被误用。
1. 先定原则:浏览器只拿用户态能力,服务端才拿高权限能力
一条底线足够解决大多数 Supabase 安全事故:
- 浏览器端只使用匿名 key + 用户会话。
- 服务端才使用更高权限能力处理后台任务。
如果你把高权限 key 直接放进前端,等于从架构层放弃了边界。
2. 认证设计,不要只想着“能不能登录”
Supabase Auth 只是登录入口,产品要真正稳定,还要想清楚:
- 登录后 session 如何续期。
- middleware 怎么保护路由。
- 服务端请求怎么拿到用户身份。
更稳的组合通常是:
- middleware 做基础路由保护。
- server action 或 route handler 执行业务读写。
- 数据层最终依赖 RLS,而不是只靠前端隐藏页面。
3. RLS 是核心,不是可选项
很多团队接 Supabase 时会先关闭 RLS,想等功能做完再补。这个决定通常会在后期付出更高代价。
建议一开始就建立最小策略:
create policy "Users can read their own projects"
on projects
for select
using (auth.uid() = user_id);
RLS 的价值不是让 SQL 更复杂,而是让权限真正沉到数据层。
4. 一个常见失败案例:前端过滤了列表,以为权限就做完了
很多项目一开始会这样写:
- 接口返回全部数据。
- 前端按当前用户过滤显示。
- 看起来每个人只能看到自己的内容。
但只要别人直接调接口,所有数据仍然可见。
根因是把“前端过滤”误当成“权限控制”。
修复方式只有一个方向:
- 服务端读取时就依赖用户上下文。
- 表级策略由 RLS 保底。
- 前端只负责展示,不负责安全。
5. 实时能力最适合“状态变化可见”的场景,不适合乱开全表订阅
Supabase realtime 很强,但也很容易被滥用。
更适合的场景是:
- 协作状态变化。
- 订单或任务状态更新。
- 通知列表追加。
不适合的是:
- 对高频大表无差别订阅。
- 页面打开就监听一堆频道。
实时不是越多越好,而是要和页面价值对应。
6. 文件存储与数据库要一起考虑生命周期
很多系统只顾着把图片传上去,却没想文件和记录的关联怎么回收。
至少要明确:
- 哪些文件公开可读。
- 哪些文件必须签名访问。
- 业务记录删除后,文件是否同步清理。
否则很容易出现数据库删了、存储还在烧钱的情况。
7. 上线前 Checklist
- 浏览器端没有暴露高权限 key。
- 认证、middleware 和服务端读写链路已打通。
- 关键表已开启 RLS,并验证过策略。
- 前端没有把“显示过滤”当成权限控制。
- 实时订阅只用于真正需要实时的场景。
- 文件存储的公开/私有边界已定义。
- 删除与清理策略已覆盖记录和文件生命周期。
- 环境变量在本地、预发、生产三套环境下可切换。
FAQ
Next.js + Supabase 适合做 MVP 吗?
很适合,尤其适合需要认证、数据库和后台能力的 MVP。但不要因为上手快就忽略 RLS 和环境隔离。
RLS 会不会让开发效率变低?
前期会增加一点建模成本,但后期能显著减少权限事故和补漏洞的代价。
Realtime 一定要开吗?
不是。只有当状态变化对用户真的有价值时,再接实时能力。


