常见访问模式:生产可用的策略模板


文档摘要

常见访问模式:生产可用的策略模板 实际项目中,权限需求往往有规律可循。本节归纳几类最常见的访问模式,作为可以直接套用的策略模板。每种模式说明适用场景、策略写法与注意事项。 模式一:完全私有(仅本人) 最严格的模式:数据完全私有,只有归属者本人能读写。 适用场景:订单、私信、个人财务记录等高度隐私数据。 策略要点:所有命令都要求 ,INSERT 用 WITH CHECK 锁定。 匿名访问:完全拒绝。 这是第 3 节详细讲过的模式,是默认的首选——不确定时,先按完全私有设计。 模式二:公开可读,本人可写 很多内容型应用(博客、论坛、商品展示)的需求是:所有人能看,但只有作者能改。 SELECT:对 public(含匿名)放行,表达式恒为真。 INSERT/UPDATE/DELETE:仅本人, 。

常见访问模式:生产可用的策略模板

实际项目中,权限需求往往有规律可循。本节归纳几类最常见的访问模式,作为可以直接套用的策略模板。每种模式说明适用场景、策略写法与注意事项。

模式一:完全私有(仅本人)

最严格的模式:数据完全私有,只有归属者本人能读写。

  • 适用场景:订单、私信、个人财务记录等高度隐私数据。
  • 策略要点:所有命令都要求 user_id = 当前用户,INSERT 用 WITH CHECK 锁定。
  • 匿名访问:完全拒绝。

这是第 3 节详细讲过的模式,是默认的首选——不确定时,先按完全私有设计。

模式二:公开可读,本人可写

很多内容型应用(博客、论坛、商品展示)的需求是:所有人能看,但只有作者能改。

  • SELECT:对 public(含匿名)放行,表达式恒为真。
  • INSERT/UPDATE/DELETE:仅本人,user_id = 当前用户
-- 公开可读 CREATE POLICY "文章公开可读" ON posts FOR SELECT TO public USING (true); -- 仅作者可写 CREATE POLICY "仅作者可写文章" ON posts FOR ALL TO authenticated USING (user_id = auth.uid()) WITH CHECK (user_id = auth.uid());
  • 注意:公开可读的 USING (true) 意味着读不受限,适合确实公开的内容;切勿对敏感数据用此模式。

模式三:需登录可见,本人可写

比「公开可读」更严:必须登录才能看,但所有人都能看到所有人的(或按某条件可见)。

  • SELECT:对 authenticated 放行(表达式按需,例如「只看已发布的」)。
  • 写入:仅本人。

适用于内部系统、社区动态等「登录才能浏览」的场景。

模式四:基于角色(RBAC)

并非所有权限都按「是不是归属者」划分,有时要按角色:管理员能操作一切,普通用户只能看。实现方式是把角色信息纳入策略判断。

两种常见做法:

  1. 用 JWT 中的角色/声明:登录时在令牌里放入角色标记(如 role: admin),策略读取并判断。优点是判断快;缺点是令牌需在角色变更后刷新。
  2. 用独立的角色/权限表:策略中用子查询查「当前用户是否是管理员」。优点是实时;缺点是每次都要查表。
-- 概念示意:管理员可读写所有,其他认证用户遵循各自策略 CREATE POLICY "管理员全权" ON products FOR ALL TO authenticated USING (auth.jwt() ->> 'role' = 'admin') WITH CHECK (auth.jwt() ->> 'role' = 'admin');

实际中常把「角色判断」与「归属判断」组合:管理员放行,否则按归属判断。

模式五:协作 / 共享

文档、白板等协作场景:创建者拥有,同时共享给一组协作者。

  • 表结构:主表有 owner_id;另有一张协作者表 (doc_id, collaborator_id)
  • 策略:当前用户是 owner,或在协作者表中存在该文档的记录。
CREATE POLICY "协作者可访问" ON documents FOR SELECT TO authenticated USING ( owner_id = auth.uid() OR EXISTS ( SELECT 1 FROM doc_collaborators c WHERE c.doc_id = documents.id AND c.collaborator_id = auth.uid() ) );

这是模式一与间接归属的组合,适用于团队协作工具。

模式六:软删除与可见性过滤

如果应用用 deleted_at 做软删除,通常希望「未删除的公开可见,已删除的对普通用户隐藏」。策略中加上可见性条件即可:

  • USING (deleted_at IS NULL) —— 只能看到未删除的行。

可见性、归属、角色这些条件可以叠加在同一策略中,组合出精细的访问控制。

模式速查表

模式 SELECT 写入 典型场景
完全私有 仅本人 仅本人 订单、私信
公开可读本人可写 全部人 仅本人 博客、商品
登录可见本人可写 登录用户 仅本人 内部系统
基于角色 按角色 按角色 管理后台
协作共享 owner + 协作者 owner + 协作者 文档协作
软删除可见性 加可见性条件 同上 含回收站的应用

RLS 调试与测试建议

  • 分身份测试:用匿名、用户 A、用户 B、管理员分别访问,验证放行与拒绝都正确。
  • 逐表检查:确认每张启用 RLS 的表,对每个命令都有预期的策略覆盖。
  • 关注 WITH CHECK:尤其 INSERT,防止冒名写入。
  • 配合日志:遇到「本该可见却看不到」时,检查策略表达式是否过严。

安全清单

把本章浓缩成一份可勾选的安全清单:

  • 每张业务表都已启用 RLS。
  • 每个命令(增删改查)都有明确策略。
  • 需要 user_id 的表已设置归属列,并有索引。
  • INSERT/UPDATE 策略有 WITH CHECK 防止冒名。
  • 服务级密钥绝不暴露到前端。
  • 已用多种身份实际测试过策略行为。
  • 公开可读仅用于真正公开的数据。

小结

完全私有、公开可读本人可写、登录可见、基于角色、协作共享、软删除可见性——这六类模式覆盖了绝大多数真实需求。理解它们的策略写法,你就能像搭积木一样组合出任意复杂的权限体系。

至此,第 5 章完成了 Supabase 安全核心的讲解。从第 6 章开始,我们在已稳固的数据与安全基础上,进入实时、存储、计算等高级能力。


发布者: 作者: 灏天文库 转发
评论区 (0)
U