行级安全性 (RLS)
使用 Drizzle,您可以为任何 Postgres 表启用行级安全性 (RLS),创建具有各种选项的策略,并定义和管理这些策略所应用的角色。
Drizzle 支持 Postgres 策略和角色的原始表示,您可以以任何方式使用它们。 这与流行的 Postgres 数据库提供者如 Neon
和 Supabase
一起工作。
在 Drizzle 中,我们为两个数据库提供者提供了特定的预定义 RLS 角色和函数,但您也可以定义自己的逻辑。
启用 RLS
如果您只想在表上启用 RLS 而不添加策略,可以使用 .enableRLS()
正如 PostgreSQL 文档中所提到的:
如果表中不存在策略,则使用默认拒绝策略,这意味着没有行可以被查看或修改。
适用于整个表的操作,如 TRUNCATE 和 REFERENCES,不受行安全性的限制。
重要
如果您向表添加策略,RLS 将自动启用。因此,在向表添加策略时无需显式启用 RLS。
角色
目前,Drizzle 支持通过几种不同的选项定义角色,如下所示。将来版本将添加对更多选项的支持。
如果数据库中已经存在角色,并且您不想让 drizzle-kit “看到”它或包含它在迁移中,可以将角色标记为现有。
策略
要充分利用 RLS,您可以在 Drizzle 表中定义策略。
信息
在 PostgreSQL 中,策略应该与现有表关联。由于策略总是与特定表相关联,我们决定将策略定义作为 pgTable
的参数进行定义。
pgPolicy 的示例,包含所有可用属性
策略选项
| |
---|
as | 可能的值为 permissive 或 restrictive |
to | 指定策略适用的角色。可能的值包括 public 、current_role 、current_user 、session_user ,或任何其他角色名作为字符串。您也可以引用一个 pgRole 对象。 |
for | 定义此策略将应用的命令。可能的值为 all 、select 、insert 、update 、delete 。 |
using | 将应用于策略创建语句的 USING 部分的 SQL 语句。 |
withCheck | 将应用于策略创建语句的 WITH CHECK 部分的 SQL 语句。 |
将策略链接到现有表
在某些情况下,您需要将策略链接到数据库中的现有表。
最常见的用例是与 Neon
或 Supabase
等数据库提供者一起使用,您需要向其现有表中添加策略。
在这种情况下,您可以使用 .link()
API。
迁移
如果您使用 drizzle-kit 来管理您的架构和角色,可能会出现您想引用未在 Drizzle 架构中定义的角色的情况。在这种情况下,您可能希望 drizzle-kit 跳过管理这些角色,而不必在您的 drizzle 架构中定义每个角色,并标记为 .existing()
。
在这些情况下,您可以在 drizzle.config.ts
中使用 entities.roles
。有关完整的参考,请参阅 drizzle.config.ts
文档。
默认情况下,drizzle-kit
不会为您管理角色,因此您需要在 drizzle.config.ts
中启用此功能。
如果您需要其他配置选项,我们可以看一些更多的示例。
您有一个 admin
角色,并希望将其排除在可管理角色列表之外
您有一个 admin
角色,并希望将其包括在可管理角色列表中
如果您使用 Neon
,并希望排除 Neon 定义的角色,则可以使用提供者选项
如果您使用 Supabase
,并希望排除 Supabase 定义的角色,则可以使用提供者选项
重要
您可能会遇到 Drizzle 与数据库提供者指定的新角色相比略显过时的情况。
在这种情况下,您可以使用 provider
选项和 exclude
除其他角色:
RLS 在视图上
使用 Drizzle,您还可以在视图上指定 RLS 策略。为此,您需要在视图的 WITH 选项中使用 security_invoker
。这是一个小示例:
与 Neon 一起使用
Neon 团队帮助我们实现了他们对我们原始策略 API 的包装器的愿景。我们定义了一个特定的
/neon
导入,其中包含 crudPolicy
函数,其中包含预定义函数和 Neon 的默认角色。
这是如何使用 crudPolicy
函数的示例:
此策略等效于:
Neon
公开了预定义的 authenticated
和 anonymous
角色及相关函数。如果您使用 Neon
进行 RLS,可以在您的 RLS 查询中使用这些标记为现有的角色以及相关函数。
例如,您可以像这样使用 Neon
预定义的角色和函数:
与 Supabase 一起使用
我们还有一个 /supabase
导入,带有一组标记为现有的预定义角色,您可以在架构中使用它。
这个导入将在未来的发布中扩展,提供更多功能和帮助器,使 RLS 和 Supabase
的使用更加简单。
例如,您可以像这样使用 Supabase
预定义的角色:
/supabase
导入还包括您可以在应用程序中使用的预定义表和函数。
这使您可以在代码中使用它,而 Drizzle Kit 将其视为现有数据库,
仅将其作为连接到其他实体的信息使用。
让我们检查一个向存在于 Supabase
的表添加策略的示例。
我们还有一个很好的示例,展示了如何将 Drizzle RLS 与 Supabase 一起使用以及如何进行实际查询。
它还包含一个很好的包装器 createDrizzle
,可以处理与 Supabase 的所有事务工作。
在即将发布的版本中,它将被转移到 drizzle-orm/supabase,允许您本地使用它。
请检查 Drizzle SupaSecureSlack repo
这是来自该库的一个实现示例:
并且可以这样使用: