PostgreSQL 的行级安全性(RLS)是从 9.5 版本开始引入的功能,允许管理员根据用户身份或其他条件控制对表中特定行的访问。这种机制在多租户环境中尤其有用,可以确保不同用户只能看到授权的数据。
什么是行级安全性(RLS)?
RLS 是一种基于行的安全策略,通过定义策略来限制数据库用户对表数据的访问权限。在启用 RLS 之前,数据库的权限控制主要在表级别,即限制用户是否可以访问某个表。通过 RLS,不同的用户可以访问同一表中的不同数据。
如何启用行级安全性
要使用 RLS,需要在表上启用行级安全性,并创建相应的策略。
-
启用行级安全性:
sqlALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
-
创建策略:
sqlCREATE POLICY policy_name ON table_name FOR {SELECT | INSERT | UPDATE | DELETE} TO {role_name} USING (condition);
- FOR 指定操作类型,可以是
SELECT
、INSERT
、UPDATE
或DELETE
。 - TO 指定该策略适用的角色。
- USING 指定条件,决定哪些行是可见或可操作的。
- FOR 指定操作类型,可以是
示例
创建表并启用 RLS
假设我们有一个 departments
表,想要限制用户只能看到自己管理的部门。
-
创建表:
sqlCREATE TABLE departments ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL UNIQUE, manager VARCHAR(255) NOT NULL );
-
插入数据:
sqlINSERT INTO departments(name, manager) VALUES('Sales', 'alice'), ('Marketing', 'bob'), ('IT', 'jack');
-
启用 RLS:
sqlALTER TABLE departments ENABLE ROW LEVEL SECURITY;
-
创建策略:
sqlCREATE POLICY department_managers ON departments FOR SELECT TO managers USING (manager = current_user);
这样,角色
alice
只能看到manager
为alice
的行。
使用 Supabase Auth 的示例
在 Supabase 中,可以结合 Auth 进行更复杂的权限控制。
-
创建表:
sqlCREATE TABLE profiles ( id UUID PRIMARY KEY, user_id UUID REFERENCES auth.users, avatar_url TEXT );
-
启用 RLS:
sqlALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
-
创建策略:
sqlCREATE POLICY user_profiles ON profiles FOR SELECT TO authenticated USING ((SELECT auth.uid()) = user_id);
这样,用户只能看到自己的个人资料。
总结
- 行级安全性(RLS) 是 PostgreSQL 中用于控制用户对表中行访问的强大工具。
- 策略 可以定义为
SELECT
、INSERT
、UPDATE
或DELETE
,并指定适用的角色和条件。 - RLS 在多租户环境中尤其有用,可以确保数据隔离和安全。