数据库

列级安全


PostgreSQL的行级安全(RLS)让您可以精细控制谁可以访问数据行。但它无法控制用户可以在行内访问哪些列。有时您需要限制对数据库中特定列的访问,列级权限(Column Level Privileges)正是为此而设计。

行级策略

行级安全(RLS)中的策略用于限制对表中行的访问。可以将其视为为每个查询添加一个WHERE子句。

例如,假设您有一个包含以下列的posts表:

  • id
  • user_id
  • title
  • content
  • created_at
  • updated_at

您可以使用RLS通过以下策略限制只有创建者才能更新内容:

1
2
3
create policy "允许所有者更新" on posts forupdate using ((select auth.uid()) = user_id);

但这样会让帖子所有者拥有更新整行的完全权限,包括所有列。

列级权限控制

要限制对列的访问权限,您可以使用 PostgreSQL权限

Postgres中有两种权限类型:

  1. 表级权限:授予表中所有列的权限
  2. 列级权限:授予表中特定列的权限

同一表可以同时拥有这两种权限。如果同时设置了两种权限,当您撤销列级权限时,表级权限仍然有效。

默认情况下,我们的表会拥有表级的UPDATE权限,这意味着authenticated角色可以更新表中的所有列。

1
2
3
4
5
6
7
8
9
revokeupdate on table public.postsfrom authenticated;grantupdate (title, content) on table public.posts to authenticated;

在上面的示例中,我们首先从authenticated角色撤销表级的UPDATE权限,然后仅授予titlecontent列的列级UPDATE权限。

如果要限制更新title列的权限:

1
2
3
4
5
revokeupdate (title) on table public.postsfrom authenticated;

这次我们是从authenticated角色撤销title列的列级UPDATE权限。由于表级UPDATE权限已经被撤销,所以不需要再次撤销。

在仪表盘中管理列权限

您可以在Supabase Studio中查看和编辑权限。

列级权限控制

在迁移中管理列权限

虽然您可以直接通过仪表板管理权限,但随着项目增长,您可能希望在迁移中管理它们。有关数据库迁移的更多信息,请参阅本地开发指南。

1

创建迁移文件

首先,生成一个新迁移来存储创建表以及行级和列级权限所需的SQL。

1
supabase migration new create_posts_table
2

将SQL添加到迁移文件

这将创建一个新迁移:supabase/migrations/<时间戳> _create_posts_table.sql。

在该文件中,添加创建posts表以及行级和列级权限的SQL。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
create 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 *都会失败