CodeGym /课程 /SQL SELF /行级访问控制:Row-Level Security (RLS)

行级访问控制:Row-Level Security (RLS)

SQL SELF
第 47 级, 课程 3
可用

如果说基于角色和表的权限像是“门口的保安”,那 Row-Level Security 就像是每个房间门口都站着一个专属保安,检查每个用户能不能进这间房。

RLS 能让用户只能操作他被允许的表里的那些行。比如:

  • 在网店里,经理只能看到自己的订单。
  • 在 CRM 平台,员工只能看到自己团队的客户。
  • 在银行系统,客户只能访问自己的账户。

RLS 怎么工作

RLS 的核心就是访问策略。策略决定了哪些表的行对某个角色或用户可见,哪些可以被改(INSERT、UPDATE、DELETE)。

默认情况下,RLS 是关闭的,你得手动开启。

为表开启 RLS

咱们先建个 orders 表,存网店订单:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    user_id INT NOT NULL,
    product_name TEXT NOT NULL,
    price NUMERIC NOT NULL
);

插入几条测试数据:

INSERT INTO orders (user_id, product_name, price)
VALUES
    (1, '智能手机', 500),
    (2, '笔记本', 1000),
    (1, '耳机', 100),
    (3, '键盘', 50);

现在给这个表开启 RLS:

ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

我们做了啥?就是激活了 RLS 机制,但还没设任何策略。没策略的话,RLS 实际上对表没啥影响。

创建访问策略

要加访问规则,用这个命令:

CREATE POLICY 策略名
ON 表名
[FOR { SELECT | INSERT | UPDATE | DELETE }]
TO 角色
USING (访问条件)
WITH CHECK (检查条件);
  • FOR:指定策略应用在哪些操作(SELECT、INSERT、UPDATE、DELETE)。不写就所有操作都用。
  • TO:指定哪些角色用这个策略。不写就是所有角色都用。
  • USING:设置什么条件下行对用户可见。
  • WITH CHECK:给 INSERT 和 UPDATE 操作用的检查条件。

例子:只能访问自己的订单

来建个策略,让用户只能看到自己的订单。假设当前用户的 id 跟表里的 user_id 一样:

CREATE POLICY user_can_view_own_orders
ON orders
FOR SELECT
USING (user_id = current_user::INT);

这段代码干了啥?

  • 策略名叫 user_can_view_own_orders。
  • 只对 SELECT 操作生效。
  • 只有 user_id 跟当前用户 id(current_user)一样的行才可见。

所以你用 user_id = 1 登录,只能看到自己的订单。

测试 RLS 效果

建两个用户:user1 和 user2。

CREATE ROLE user1 LOGIN PASSWORD 'password1';
CREATE ROLE user2 LOGIN PASSWORD 'password2';

给这俩角色授权访问表:

GRANT SELECT ON orders TO user1, user2;

现在切换到 user1,试试查表:

SELECT * FROM orders;

结果:你只能看到 user_id = 1 的行。

INSERT 策略

比如我们想让用户只能添加属于自己的订单(也就是 user_id 必须等于当前用户 id)。

建个 INSERT 策略:

CREATE POLICY user_can_insert_own_orders
ON orders
FOR INSERT
WITH CHECK (user_id = current_user::INT);

现在,如果 user1 想插入 user_id 不是 1 的订单,会报错。

UPDATE 和 DELETE 策略

同理可以建修改和删除的策略。比如:

只能改自己的数据:

CREATE POLICY user_can_update_own_orders
ON orders
FOR UPDATE
USING (user_id = current_user::INT)
WITH CHECK (user_id = current_user::INT);

只能删自己的数据:

CREATE POLICY user_can_delete_own_orders
ON orders
FOR DELETE
USING (user_id = current_user::INT);

多策略同时用

你可以给一个表建多个策略,都会一起生效。如果一个角色有多条规则,PostgreSQL 会都检查一遍(逻辑与)。

RLS 检查和调试

想查表上有哪些策略,用:

\di+ 表名

想临时关掉 RLS(比如管理员用),执行:

ALTER TABLE orders DISABLE ROW LEVEL SECURITY;

超级管理员 SUPERUSER 默认不受 RLS 限制,可以看到所有数据。

RLS 配置常见错误

常见错误有:

  • 忘了用 ALTER TABLE ... ENABLE ROW LEVEL SECURITY 开启 RLS。
  • 没给所有操作(SELECT、INSERT、UPDATE、DELETE)设策略。
  • USING 和 WITH CHECK 条件写错。比如没检查 user_id,就可能让所有行都能访问。

Row-Level Security 是 PostgreSQL 里最强大的安全工具之一。它能精确到每一行控制访问,还能自动化管理权限,特别适合对数据安全要求高的复杂应用。

2
任务
SQL SELF, 第 47 级, 课程 3
已锁定
复杂策略:读取和编辑权限
复杂策略:读取和编辑权限
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION