Supabase/PostgreSQL RLS规则触发profiles表无限递归错误求助
问题定位与解决方案
递归错误原因
你的第二个RLS策略中,USING子句里的SELECT 1 FROM profiles ...会触发profiles表的RLS规则(因为你已经为该表启用RLS)。这个内部查询会再次应用所有针对profiles的SELECT策略,包括当前的管理员权限策略,形成无限递归调用,最终被PostgreSQL检测到并抛出错误。
正确的实现方式
要判断当前用户是否为admin,需要绕过RLS查询自己的profile记录(避免触发策略递归),以下是两种可行方案:
方案1:单独编写管理员权限策略
修改管理员策略,在查询profiles时使用bypassrls关键字跳过RLS检查:
CREATE POLICY "Enable read for admins to all profiles" ON "public"."profiles" AS PERMISSIVE FOR SELECT TO authenticated USING ( EXISTS ( SELECT 1 FROM profiles bypassrls WHERE id = auth.uid() AND role = 'admin' ) );
方案2:合并两个策略(更简洁)
将“用户查看自身”和“管理员查看所有”的逻辑合并到同一个策略中,减少规则数量:
CREATE POLICY "Allow self read or admin full read" ON "public"."profiles" AS PERMISSIVE FOR SELECT TO authenticated USING ( -- 普通用户仅能查看自身记录 auth.uid() = id -- 管理员可查看所有记录 OR EXISTS ( SELECT 1 FROM profiles bypassrls WHERE id = auth.uid() AND role = 'admin' ) );
额外说明
bypassrls仅在当前策略的内部查询中生效,不会全局关闭RLS,只是避免递归触发策略。- 确保
profiles表的role字段已正确赋值,管理员用户的role值确实为'admin'。
内容的提问来源于stack exchange,提问作者Henner
相关产品推荐
相关产品推荐

