列级别安全
PostgreSQL 的 行级别安全性 (RLS) 使您能够对数据行的访问进行细粒度控制。但是,它不能控制访问行内哪些列。有时您希望限制对数据库中特定列的访问。列级别权限允许您做到这一点。
这是一个高级功能。我们不建议大多数用户使用列级别权限。相反,我们建议结合使用 RLS 策略和专门的表来处理用户角色。
受限角色无法在受影响的表上使用通配符运算符 (*)。不要使用 SELECT * FROM <受限表>; 或其 API 等效项,而必须显式指定列名。
行级别的策略#
行级别安全性的 (RLS) 策略用于限制对表内行的访问。可以将它们视为为每个查询添加一个 WHERE 子句。
例如,假设您有一个名为 posts 的表,其中包含以下列
iduser_idtitlecontentcreated_atupdated_at
您可以使用 RLS 限制更新,使其仅限于创建该内容的的用户,策略如下
1create policy "Allow update for owners" on posts for2update3 using ((select auth.uid()) = user_id);但是,这赋予了帖子所有者完全访问权限来更新该行,包括所有列。
列级别的权限#
要限制对列的访问,可以使用 权限。
Postgres 中有两种类型的权限
- 表级别:授予表所有列的权限。
- 列级别:授予表特定列的权限。
您可以在同一张表上拥有这两种类型的权限。如果您同时拥有这两种权限,并且撤销了列级别权限,则表级别权限仍然有效。
默认情况下,我们的表将具有表级别的 UPDATE 权限,这意味着 authenticated 角色可以更新表中的所有列。
1revoke2update3 on table public.posts4from5 authenticated;67grant8update9 (title, content) on table public.posts to authenticated;在上面的示例中,我们正在从 authenticated 角色撤销表级别的 UPDATE 权限,并授予仅对 title 和 content 列的列级别 UPDATE 权限。
如果我们要限制对 title 列的更新访问
1revoke2update3 (title) on table public.posts4from5 authenticated;这一次,我们正在从 authenticated 角色撤销 title 列的列级别 UPDATE 权限。我们不需要撤销表级别的 UPDATE 权限,因为它已经被撤销了。
在仪表板中管理列权限#
列级别权限是一个强大的工具,但它们也相当高级,并且在许多情况下,不适合常见的访问控制需求。因此,我们有意将此功能的 UI 移动到仪表板中的功能预览部分。
您可以在 Supabase Studio 中查看和编辑权限。

在迁移中管理列权限#
虽然您可以直接从仪表板管理权限,但随着项目的发展,您可能希望在迁移中管理它们。请阅读 本地开发 指南中的数据库迁移。
将 SQL 添加到您的迁移文件
这将创建一个新的迁移:supabase/migrations/<timestamp> _create_posts_table.sql。
将 SQL 添加到该文件,以创建具有行和列级别权限的 posts 表。
1create table2posts (3id bigint primary key generated always as identity,4user_id text,5title text,6content text,7created_at timestamptz default now()8updated_at timestamptz default now()9);1011-- Add row-level security12create policy "Allow update for owners" on posts for13update14using ((select auth.uid()) = user_id);1516-- Add column-level security17revoke18update19(title) on table public.posts20from21authenticated;使用列级别权限的注意事项#
- 如果您关闭了列权限,您将无法使用该列。
- 所有操作(插入、更新、删除)以及使用
select *都会失败。