跳到主要内容

权限与 RLS 问题

权限问题常见表现为 permission denied、HTTP 401/403、查询返回空数组或写入失败。排查时需要同时检查角色授权和 RLS 策略。

判断问题类型

现象优先排查
permission denied for table表权限、schema 权限
permission denied for sequence自增序列权限
查询成功但返回空数组RLS using 条件不匹配
插入或更新失败RLS with check 条件不匹配
未登录用户访问失败anon 角色或登录状态

检查表权限

select grantee, privilege_type
from information_schema.role_table_grants
where table_schema = 'public'
and table_name = 'todos'
order by grantee, privilege_type;

如果缺少权限,可按需授权:

grant usage on schema public to authenticated;
grant select, insert, update on public.todos to authenticated;
grant usage, select on all sequences in schema public to authenticated;

检查 RLS 状态

select schemaname, tablename, rowsecurity
from pg_tables
where schemaname = 'public'
and tablename = 'todos';

查看策略:

select policyname, cmd, roles, qual, with_check
from pg_policies
where schemaname = 'public'
and tablename = 'todos';

空结果排查

如果查询没有报错但返回空数组,通常是 RLS 条件过滤了所有行。检查:

  • 当前用户是否已登录。
  • 表中归属字段是否等于 auth.uid()
  • 策略是否使用了正确角色,例如 authenticated
  • 查询是否经过视图,且视图是否绕过 RLS。
select auth.uid();

auth.uid()null 时,基于用户身份的策略会拒绝访问。

修复建议

  • 前端直连表必须先设计 RLS,再开放表权限。
  • insertupdate 应同时检查 WITH CHECK,避免用户写入他人数据。
  • 为 RLS 过滤字段创建索引,避免权限策略拖慢查询。
  • 服务端管理操作建议走云函数或云托管,不要放宽前端 RLS。

详细策略示例请参考 基础权限