RLS Simplified
基本总结 #
🌐 Basic summary
行级安全(RLS)策略:自动应用到数据库查询的 WHERE 或 CHECK 条件
🌐 Row-Level Security (RLS) Policy: A WHERE or CHECK condition applied automatically to database queries
主要特点:
🌐 Key features:
- 无需显式添加到每个查询中,这使得它非常适合管理未知实体(例如使用匿名或已认证角色的用户)的行访问。
- 可以为特定操作设置(例如,SELECT、INSERT)
- 可以针对特定的数据库角色(例如,“匿名”、“已认证”)
与常规情况相比:
🌐 Contrast with regular conditions:
- 常规条件:适用于所有角色,需要手动添加到每个查询中
- RLS 策略:自动应用于指定的操作和角色
实操演示各种情况 #
🌐 Hands on walk-through for conditions
使用: #
🌐 USING:
USING 关键字会检查行的值,以确定是否应该让查询可见。
🌐 The USING keyword inspects the value of row to see if it should be made visible to the query.
当你使用 SELECT、UPDATE 或 DELETE 时,你必须使用 WHERE 语句来查找特定的行:
🌐 When you SELECT, UPDATE, or DELETE, you have to use a WHERE statement to search for specific rows:
1-- select2select *3from some_table4where id = 5;56-- update7update some_table8set id = 69where id = 5;1011-- delete12delete from some_table13where id = 6;即使你没有使用 WHERE 语句,它仍然会有一个隐含的:
🌐 Even when you don't use a WHERE statement, there's still an implicit one:
1-- ...your query2WHERE true;USING 条款会在 WHERE 语句后追加更多内容:
🌐 The USING clause appends more to the WHERE statement:
1-- Your Using condition2USING (3 (select auth.uid()) = user_id4);56-- Your query without RLS:7SELECT * FROM some_table8WHERE id = 5 OR id = 6;910-- Your query after RLS11SELECT * FROM some_table12WHERE13 (id = 5 OR id = 6)14 AND15 (select auth.uid()) = user_id) -- <--- added by the USING clause;带检查: #
🌐 WITH CHECK:
假设你有一个个人资料表。嗯,你不希望用户在插入数据时可以修改他们的 user_id,对吧?
🌐 Say you have a profile table. Well, you don't want user's to be able to modify their user_id when they make an insert, do you?
WITH CHECK 条件会检查正在被添加或修改的值。对于 INSERT,你可以单独使用它。无需使用 using 子句:
🌐 The WITH CHECK condition inspects values that are being added or modified. For INSERT you'd use it by itself. There's no need for a using clause:
1-- Allow users to add to table, but make sure their user_id matches the one in their JWT:23create policy "Allow user to add posts"4on "public"."posts"5as PERMISSIVE6for INSERT7to authenticated8with check(9 (select auth.uid()) = user_id10);1112-- Example: failing insert13INSERT INTO posts14VALUES (<false id>, <comment>);1516-- Example: successful insert17INSERT INTO posts18VALUES (<real id>, <comment>);INSERT 不依赖 WHERE 子句,但它们可以有约束。在这种情况下,RLS 相当于对某一列的 CHECK 约束,例如:
🌐 INSERTs do not rely on WHERE clauses, but they can have constraints. In this case, the RLS acts as a CHECK constraint against a column, e.g.:
1ALTER TABLE table_name2ADD CONSTRAINT constraint_name CHECK (condition);它和普通的 CHECK 约束的区别在于,它只针对某些角色或方法激活。
🌐 What distinguishes it from normal CHECK constraints is that it is only activate for certain roles or methods.
更新: #
🌐 UPDATEs:
更新要更改的行的两个过滤器,然后向表中添加新值,因此它需要同时使用 USING 和 WITH CHECK 条件:
🌐 UPDATE both filters for rows to change and then adds new values to the table, so it requires both USING and WITH CHECK conditions:
1create policy "Allow user to edit their stuff"2on "public"."<SOME TABLE NAME>"3as RESTRICTIVE4for UPDATE5to authenticated6using (7 (select auth.uid()) = user_id8)9with check(10 (select auth.uid()) = user_id11);