结合 Auth 的用户隔离:私有数据模式 策略的语法掌握后,最核心的应用场景就是「用户数据隔离」——让每个用户只能访问自己的数据。本节讲解如何用 RLS 实现这一目标,以及「行归属标识」这一关键设计。 用户隔离的本质 用户隔离要解决的问题是:同一张表里混着所有人的数据,如何让用户 A 只看到 A 的、用户 B 只看到 B 的? 答案就藏在第 4 章——每个用户都有唯一的 id(UUID)。只要每行数据都标注「它属于哪个用户」,策略就能据此判断:只有行的归属者 id 与当前请求者 id 相等时,才放行。 关键:行上要有归属标识 实现隔离的前提是:业务表必须有标识「这行属于谁」的列。通常是一列 (UUID),引用认证系统的用户 id。 有了 列,策略就能用 来过滤。
策略的语法掌握后,最核心的应用场景就是「用户数据隔离」——让每个用户只能访问自己的数据。本节讲解如何用 RLS 实现这一目标,以及「行归属标识」这一关键设计。
用户隔离要解决的问题是:同一张表里混着所有人的数据,如何让用户 A 只看到 A 的、用户 B 只看到 B 的?
答案就藏在第 4 章——每个用户都有唯一的 id(UUID)。只要每行数据都标注「它属于哪个用户」,策略就能据此判断:只有行的归属者 id 与当前请求者 id 相等时,才放行。
实现隔离的前提是:业务表必须有标识「这行属于谁」的列。通常是一列 user_id(UUID),引用认证系统的用户 id。
orders 表: id | user_id(归属者)| amount | ... ---|------------------|--------|---- A | 用户A的UUID | 100 | ... B | 用户B的UUID | 200 | ...
有了 user_id 列,策略就能用 user_id = 当前用户 id 来过滤。因此设计表时(第 2 章)就要为需要隔离的表预留归属列——这是 RLS 能发挥作用的基础。
以订单表为例,一套完整的「私有数据」策略覆盖四个命令:
合并起来,可用一条 ALL 策略表达(概念示意):
-- 用户只能读写属于自己的订单 CREATE POLICY "订单私有" ON orders FOR ALL TO authenticated USING (user_id = auth.uid()) WITH CHECK (user_id = auth.uid());
auth.uid() 返回当前登录用户的 id;USING 管读/改/删(针对已存在的行),WITH CHECK 管插入与更新后的新行。两端都用 user_id = 当前用户 id 锁定,用户就只能触碰自己的数据。
特别注意 INSERT 的 WITH CHECK。如果只写了 SELECT/UPDATE/DELETE 策略却忘了 INSERT,或 INSERT 策略没有 WITH CHECK,用户就可能插入一行 user_id 是别人的数据——冒充他人。完整的私有策略必须在 WITH CHECK 中强制 user_id = 当前用户 id。
一个常见错误:前端用当前用户填表,开发者以为「前端传的就是对的」,于是不给 INSERT 加 WITH CHECK。但客户端的任何值都可被篡改,安全必须以服务端(数据库)的强制校验为准。
为了减少出错与简化前端,常用触发器在插入时自动把 user_id 填为当前用户,而不依赖前端传入。这样:
WITH CHECK 形成双重保险。触发器逻辑:在 INSERT 之前,把 NEW 行的 user_id 设为当前用户 id。这是 Supabase 中非常常见的模式。
有些表的归属不止「直接拥有者」一种,例如:
owner_id,还需一张「协作者」关联表,策略里用子查询判断「当前用户是 owner 或在协作者列表中」。order_id 关联到订单再找到用户。策略中用 EXISTS 子查询跨越层级判断。-- 概念示意:订单项通过所属订单间接归属用户 CREATE POLICY "订单项随订单隔离" ON order_items FOR SELECT TO authenticated USING ( EXISTS ( SELECT 1 FROM orders o WHERE o.id = order_items.order_id AND o.user_id = auth.uid() ) );
这类「间接归属」在规范化设计中很常见,理解子查询在策略中的用法就能处理任意层级的归属关系。
带 RLS 的查询,数据库会在内部把策略表达式附加到 WHERE 子句上,相当于自动加了一层过滤。需要注意:
用户隔离的核心是「行上的归属列 + 基于 id 的策略比较」:表必须有 user_id(或可推导的归属),策略用 user_id = 当前用户 id 限定读写,并用触发器与 WITH CHECK 防止冒名。掌握这一模式,你就实现了 Supabase 安全体系的灵魂。下一节归纳几类常见的访问模式,作为实战模板。