使用 prisma 和 postgres 的行级安全性

Row level security using prisma and postgres

我正在使用带有 postgres 数据库的 prisma 和 yoga graphql 服务器。

我想为我的 graphql 查询实现授权。我看到像 graphql-shield 这样的解决方案很好地解决了 column level security - 这意味着我可以定义一个权限并根据它阻止或允许特定的 table 或数据列(在 graphql 术语中,阻止 a整个实体或特定字段)。

我坚持的部分是 row level security - 按行包含的数据过滤行 - 假设我想允许登录用户仅查看与其相关的数据,因此取决于user_id 列中的值我会允许或阻止对该行的访问(登录用户就是一个例子,但这一类型还有其他用例)。

这种类型的安全性需要 运行查询以检查当前用户可以访问哪些行,但我找不到使用 prisma 实现此功能的方法(这并不可怕)。

如果我在没有 prisma 的情况下工作,我会在每个解析器的级别上实现它,但是由于我将查询转发给 prisma,所以我不控制嵌套查询的内部解析器。

但我确实想使用 prisma,所以我们的一个想法是使用 postgres policy 在数据库级别处理它。这可以按如下方式工作:

  1. 我们 运行 的每个查询都将被“开始交易”和“提交交易”包围
  2. 在查询之前我想 运行 “set local context.user_id to 5”
  3. 然后我想 运行 查询(策略会根据 current_setting(‘context.user_id’))
  4. 过滤结果

为此,我需要 prisma 来允许我向 运行 的每个查询添加 pre/post 查询,或者让我为数据库设置上下文。

但是这些选项在 prisma 中不可用。

有什么想法吗?

您可以使用 prisma-client 而不是 prisma-binding

使用 prisma-binding,您定义顶级解析器,然后 委托给 prisma 进行所有嵌套。

另一方面,prisma-client 只有 return 个类型的标量值 ,您需要为关系定义解析器。这意味着您可以完全控制您 return 的内容,即使对于嵌套查询也是如此。 (示例见 documentation

我建议您使用 prisma-client 在字段上应用安全过滤器。

根据您希望采用的方法,我绝对建议您查看您正在考虑的 Graphile. It approaches row-level security essentially the same way。不幸的是,在这方面,Prisma 似乎无法帮助您摆脱编写传统 REST 风格的控制器方法。