You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为PostgreSQL(Supabase)中一对多关系的companies表配置RLS更新策略?

如何为PostgreSQL(Supabase)中一对多关系的companies表配置RLS更新策略?

嘿,我来帮你把这个理清楚!先从你最困惑的auth说起——

首先,auth是什么?

auth是Supabase内置的一套辅助函数集合,专门用来快速获取当前已登录用户的核心信息,不用你自己写复杂的查询去关联用户表。比如:

  • auth.email():返回当前登录用户的邮箱(对应你users表里的email字段)
  • auth.uid():返回当前登录用户的唯一ID(对应你users表里的id字段,这个比邮箱更可靠,因为邮箱可能被修改)

Supabase给的那个starter模板其实是给有email字段的表用的(比如users表或者profiles表),但你的companies表里根本没有email字段,所以直接用肯定不行,得根据你的表结构改。

先理清楚你的表关联逻辑

你的表是这样关联的:
users.id ↔ profiles.id(一对一,每个用户对应一个profile)
profiles.company_id → companies.id(多对一,多个用户属于同一个公司,Mark的company_id为NULL,不属于任何公司)

合理的更新权限逻辑应该是:只有属于某个公司的用户,才能更新这个公司的记录,对吧?

具体的RLS更新策略代码

首先确保companies表已经开启了RLS(如果还没开的话):

ALTER TABLE public.companies ENABLE ROW LEVEL SECURITY;

然后创建符合你需求的更新策略:

CREATE POLICY "允许所属公司的用户更新公司信息"
ON public.companies
FOR UPDATE
USING (
  -- 核心逻辑:检查当前登录用户的profile是否关联到要更新的公司
  EXISTS (
    SELECT 1
    FROM public.profiles
    WHERE profiles.id = auth.uid()  -- 用用户ID关联,比邮箱更稳定
      AND profiles.company_id = companies.id
  )
)
WITH CHECK (
  -- 确保更新操作不会让用户脱离该公司(这里逻辑和USING一致,因为更新公司一般不会改ID)
  EXISTS (
    SELECT 1
    FROM public.profiles
    WHERE profiles.id = auth.uid()
      AND profiles.company_id = companies.id
  )
);

关键部分拆解

  • USING子句:用来筛选出当前用户有权操作的行——只有当用户的profile关联到这个公司时,才能看到并尝试更新这条公司记录。
  • WITH CHECK子句:用来验证用户提交的更新内容是否符合规则——防止用户通过某种方式把公司改成不属于自己的(不过这里更新公司一般只会改name,不会改id,所以和USING逻辑一致就好)。
  • 为什么用EXISTS?因为它是高效的存在性检查,只要找到匹配的记录就会返回true,不用返回所有数据。

特殊情况说明

像Mark那样company_id为NULL的用户,这个策略会自动拒绝他更新任何公司记录,因为找不到匹配的关联,完全符合预期。如果之后你需要更精细的权限(比如只有公司的管理员能更新),只需要在profiles表加个is_admin字段,然后在策略里加个AND profiles.is_admin = true的条件就行。

备注:内容来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 12:49:06