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

Postgres行级安全(RLS)插入策略中查询值引用问题排查

解决Postgres RLS插入策略的字段引用问题

你遇到的核心问题是子查询中对插入字段的引用歧义:Postgres会把你写的owner_id和contact_id默认解析为子查询里connection c表的字段,而不是你要插入的新行的字段。这就导致只要目标用户在connection表的任何行存在,就会触发冲突,完全偏离了你的预期逻辑。

修正后的RLS策略

你需要用Postgres的NEW关键字来明确引用待插入的新行数据,修正后的策略如下:

CREATE POLICY "Participants INSERT" ON public.connection FOR INSERT WITH CHECK (
  auth.uid() = NEW.owner_id
  AND NOT EXISTS(
    SELECT * FROM public.connection c WHERE (
      (c.owner_id = NEW.owner_id AND c.contact_id = NEW.contact_id)
      OR (c.contact_id = NEW.owner_id AND c.owner_id = NEW.contact_id)
    )
  )
  AND EXISTS(
    SELECT * FROM public.request r WHERE (
      r.sender_id = NEW.contact_id AND r.recipient_id = NEW.owner_id
    )
  )
);

关键修正点解释

  1. 用NEW指代插入行:NEW是Postgres触发器和RLS策略中的特殊变量,专门用来引用即将插入的新行的字段值。通过NEW.owner_id和NEW.contact_id,你明确告诉数据库:我要对比的是这次插入的owner和contact,而不是子查询表中的任意行。
  2. 逻辑验证:
    • 确保当前用户是插入连接的owner_id(auth.uid() = NEW.owner_id)
    • 检查双方不存在任何形式的双向连接(无论是我加他还是他加我)
    • 确认存在对应的请求记录(对方发送给当前用户的请求)

测试建议

你可以用以下语句测试策略是否生效:

-- 替换为实际的用户UUID
INSERT INTO connection (owner_id, contact_id) VALUES ('你的用户UUID', '请求方用户UUID');

如果满足所有条件(存在对应请求、无现有连接),插入会成功;否则会触发RLS违规错误,符合你的预期逻辑。

内容的提问来源于stack exchange,提问作者Max

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 11:18:12