【问题标题】:Row level security using prisma and postgres使用 prisma 和 postgres 的行级安全性
【发布时间】:2019-05-10 00:22:34
【问题描述】:

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

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

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

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

如果我在没有 prisma 的情况下工作,我会在每个解析器的级别实现这一点,但由于我将查询转发到 prisma,因此我无法控制嵌套查询的内部解析器。

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

  1. 我们运行的每个查询都将被“开始事务”和“提交事务”包围
  2. 在查询之前我想运行“将本地 context.user_id 设置为 5”
  3. 然后我想运行查询(策略会根据 current_setting('context.user_id') 过滤结果)

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

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

有什么想法吗?

【问题讨论】:

  • 如果没有架构,我无法给出明确的答案,但您是否尝试使用 ((id)::name = SESSION_USER) 或这些行中的内容创建策略。 SESSION_USER 是用于连接数据库的角色。
  • 我假设您使用prisma-binding 进行转发。也许使用prisma-client 会是一个更好的选择,所以你会在解析器中实现这个逻辑? (这也适用于嵌套查询)
  • 关于会话用户,我通过 prisma 与数据库的连接始终具有相同的用户和角色。用户在应用程序级别进行管理,而不是数据库。我认为对于 prisma 的每个查询甚至都不可能具有特定的角色。如果这是可能的,它可以解决问题。有没有可能,我错过了什么?

标签: postgresql graphql prisma row-level-security prisma-graphql


【解决方案1】:

对于您希望采用的方法,我绝对建议您查看Graphile。它本质上接近您正在考虑的行级安全性the same way。不幸的是,Prisma 似乎并不能帮助您摆脱在这方面编写传统的 REST 风格的控制器方法。

【讨论】:

    【解决方案2】:

    您可以使用prisma-client 代替prisma-binding

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-23
      • 1970-01-01
      • 2017-05-02
      • 2021-02-04
      • 1970-01-01
      • 2021-07-20
      • 2021-04-10
      • 2016-02-24
      相关资源
      最近更新 更多