Supabase RLS配置问题:基于app_meta_data角色数组的行级访问控制失效
解决Supabase RLS规则中基于app_metadata角色数组的权限判断问题
你之前的RLS规则失效,核心原因是JSON类型的数组无法直接用IN操作符判断元素是否存在:auth.jwt() -> 'app_metadata' -> 'role'返回的是jsonb类型的数组,而IN需要的是PostgreSQL原生数组或离散值集合,类型不匹配导致规则不生效。
下面提供两种可行的修正方案:
方案1:将JSON数组转为文本数组后用IN判断
通过jsonb_array_text()函数把JSON数组转换成PostgreSQL文本数组,再用IN检查元素:
(auth.uid() = user_id OR 'admin' IN (SELECT jsonb_array_text(auth.jwt()->'app_metadata'->'role')))
方案2:用JSONB包含操作符@>直接判断
PostgreSQL的@>操作符可以直接判断JSON数组是否包含指定元素,写法更简洁:
(auth.uid() = user_id OR auth.jwt()->'app_metadata'->'role' @> '"admin"'::jsonb)
注意:这里需要把
admin转成带双引号的JSON字符串("admin"),再强转为jsonb类型,才能和目标JSON数组匹配。
验证小技巧
你可以在Supabase SQL编辑器中执行以下语句,确认当前用户的角色数组处理结果:
-- 查看原始JSON数组 SELECT auth.jwt()->'app_metadata'->'role'; -- 查看转换后的文本数组 SELECT jsonb_array_text(auth.jwt()->'app_metadata'->'role'); -- 验证包含判断 SELECT auth.jwt()->'app_metadata'->'role' @> '"admin"'::jsonb;
内容的提问来源于stack exchange,提问作者grayson
相关产品推荐
相关产品推荐

