Supabase指定邮箱SELECT行级安全策略不生效问题排查
Supabase RLS策略不生效返回空结果排查
按出现概率从高到低排查以下问题即可:
- 未给对应角色授予表的基础访问权限
RLS策略的执行前提是数据库角色本身拥有表的操作权限,很多人会跳过这步配置。RLS不会替代基础的GRANT权限配置,缺少授权时接口会直接返回空数组而非权限报错。执行以下SQL补全授权即可:-- 给所有已登录用户授予policy_test表的查询权限 GRANT SELECT ON public.policy_test TO authenticated; auth.email()取值与预期不一致auth.email()读取的是请求携带JWT中缓存的邮箱字段,不会实时拉取auth.users表的最新值:- 如果是绑定/修改邮箱后没有重新登录刷新JWT,JWT内存储的旧值会和你配置的目标邮箱不匹配
- 注意大小写、前后隐形空格的完全匹配,比如JWT内存储
Diego@example.com时,和你写的全小写字符串不会判定为相等
排查时可以在请求上下文执行select auth.email();,确认返回值和策略里写的diego@example.com完全一致。
- 请求携带的密钥/Token不符合预期
- 如果请求头里带的是
service_role密钥,会默认绕过所有RLS策略,和你手动关闭RLS的效果一致,这种场景下策略本身不会生效 - 如果携带的用户JWT过期、格式错误、不属于对应用户,
auth.email()会返回null,自然无法匹配策略条件
可以先在Supabase SQL编辑器中模拟登录用户上下文测试策略有效性:
如果上述查询能正常返回数据,说明策略本身配置正确,问题出在Insomnia请求的头信息配置上,核对你携带的-- 切换到已登录用户角色 SET ROLE authenticated; -- 模拟携带对应用户的JWT claims SET request.jwt.claims TO '{"email":"diego@example.com","sub":"你的用户实际UUID"}'; -- 执行测试查询 SELECT * FROM public.policy_test;apikey是不是项目的anon公钥、Authorization头的Bearer Token是不是对应账号的最新有效JWT即可。 - 如果请求头里带的是
- 策略配置存在额外限定
核对你创建的策略是否额外加了TO角色限定,比如误将策略生效范围设为postgres等内置角色,导致普通登录用户无法命中策略。你贴出的SQL默认对所有角色生效,这个问题概率较低。
内容的提问来源于stack exchange,提问作者Diego Ulloa
相关产品推荐
相关产品推荐

