列级安全
PostgreSQL的行级安全(RLS)让您可以精细控制谁可以访问数据行。但它无法控制用户可以在行内访问哪些列。有时您需要限制对数据库中特定列的访问,列级权限(Column Level Privileges)正是为此而设计。
这是一个高级功能。我们不建议大多数用户使用列级权限。相反,我们建议结合使用RLS策略和专门处理用户角色的表。
受限角色不能在受影响表上使用通配符操作符(*
)。您必须明确指定列名,而不能使用SELECT * FROM <受限表>;
或其API等效语句。
行级策略
行级安全(RLS)中的策略用于限制对表中行的访问。可以将其视为为每个查询添加一个WHERE
子句。
例如,假设您有一个包含以下列的posts
表:
id
user_id
title
content
created_at
updated_at
您可以使用RLS通过以下策略限制只有创建者才能更新内容:
123create policy "允许所有者更新" on posts forupdate using ((select auth.uid()) = user_id);
但这样会让帖子所有者拥有更新整行的完全权限,包括所有列。
列级权限控制
要限制对列的访问权限,您可以使用 PostgreSQL权限。
Postgres中有两种权限类型:
- 表级权限:授予表中所有列的权限
- 列级权限:授予表中特定列的权限
同一表可以同时拥有这两种权限。如果同时设置了两种权限,当您撤销列级权限时,表级权限仍然有效。
默认情况下,我们的表会拥有表级的UPDATE
权限,这意味着authenticated
角色可以更新表中的所有列。
123456789revokeupdate on table public.postsfrom authenticated;grantupdate (title, content) on table public.posts to authenticated;
在上面的示例中,我们首先从authenticated
角色撤销表级的UPDATE
权限,然后仅授予title
和content
列的列级UPDATE
权限。
如果要限制更新title
列的权限:
12345revokeupdate (title) on table public.postsfrom authenticated;
这次我们是从authenticated
角色撤销title
列的列级UPDATE
权限。由于表级UPDATE
权限已经被撤销,所以不需要再次撤销。
在仪表盘中管理列权限
您可以在Supabase Studio中查看和编辑权限。
在迁移中管理列权限
虽然您可以直接通过仪表板管理权限,但随着项目增长,您可能希望在迁移中管理它们。有关数据库迁移的更多信息,请参阅本地开发指南。
将SQL添加到迁移文件
这将创建一个新迁移:supabase/migrations/<时间戳> _create_posts_table.sql。
在该文件中,添加创建posts
表以及行级和列级权限的SQL。
123456789101112131415161718192021create tableposts (id bigint primary key generated always as identity,user_id text,title text,content text,created_at timestamptz default now()updated_at timestamptz default now());-- 添加行级安全策略create policy "允许所有者更新" on posts forupdateusing ((select auth.uid()) = user_id);-- 添加列级安全策略revokeupdate(title) on table public.postsfromauthenticated;
使用列级权限时的注意事项
- 如果关闭某列的权限,将完全无法使用该列
- 所有操作(插入、更新、删除)以及使用
select *
都会失败