【问题标题】:GraphQL - Security - Protect nested dataGraphQL - 安全 - 保护嵌套数据
【发布时间】:2019-03-02 20:01:11
【问题描述】:

假设我的应用是电子商务。有UsersOrdersProducts

您需要通过身份验证(使用 JWT 令牌)才能访问您的 user 数据和您的 orders。此检查在解析器中完成。

但是,Products 是公开的。无需登录即可查看产品。

当然,UserOrdersOrderProducts

如果前端有人在做这个查询怎么办:

query IAmEvil {
  products {
    orders {
      users {
         id
         name
         email
       }
    }
  }
}

这个未经身份验证的人可以访问users 数据。我怎样才能防止这种情况发生?

我是否必须在所有解析器中为所有嵌套查询添加规则?

相关文档:

https://www.apollographql.com/docs/guides/security.html https://www.howtographql.com/advanced/4-security/ https://blog.apollographql.com/securing-your-graphql-api-from-malicious-queries-16130a324a6b https://www.prisma.io/forum/t/graphql-security-protect-nested-data/4519

【问题讨论】:

    标签: security nested graphql apollo resolver


    【解决方案1】:

    简短的回答是肯定的,但不是在每个级别进行嵌套。

    对于任何请求,您都有用户(或缺少用户)和进入图表的路径。这与您必须授权请求的 RESTful 类型请求完全相同。虽然 b/c 可以在任何地方添加解析器,但它更难。

    关于 facebook 如何处理这个问题的最佳演讲可能在这里https://blog.apollographql.com/graphql-at-facebook-by-dan-schafer-38d65ef075af

    要点是他们有一个函数负责获取和授权解析器使用。

    【讨论】:

      【解决方案2】:

      一个可以说是更优雅的解决方案是利用行级安全性 (RLS) 来控制任何特定用户可以访问的数据。虽然这种方法增加了一些复杂性,但如果您的 API 由具有不同访问权限的不同角色的用户访问,则它特别有吸引力。这实际上是postgraphile 处理身份验证的方式。

      您还可以潜在地使用模式指令来保持干燥,并将一些通用访问逻辑应用于一组单独的字段。 Apollo 的文档实际上有an example of doing just that

      除此之外,是的,您的解析器需要具有上下文感知能力并包含限制您公开的数据的逻辑。

      重要的是要指出,这些问题首先也可以追溯到良好的架构设计。例如,仅仅因为存在关系并不意味着它需要(或应该)暴露给客户。一个订单可能包含一个或多个产品,如果客户需要显示订单历史记录,那么在 Order 类型上公开一个 products 字段是有意义的。另一方面,客户真的需要知道给定产品的所有订单吗?

      同样,如果我们在Order 上有一个users 字段,在任何特定于用户的上下文之外,这样的字段自然只会反映与订单关联的用户(很可能只是一个用户)。在单个订单上将所有用户作为一个字段返回是没有意义的。由于 GraphQL 的自上而下的性质,一个字段通常只会被限制在其父级的上下文中。因此,可能只需要担心根级别的用户上下文。

      一个不同的、任意的例子:

      query MyOrders {
        orders { # check context for user and limit results to just the logged in user
          user { # user will be based on parent (the order), no need to check context
            orders { # orders will be based on parent (the user), no need to check context  
            }
          }
        }
      }
      

      通过合理的架构设计,其他类型字段的解析器不一定需要进行任何额外的上下文检查。

      【讨论】:

      • 能否详细说明RLS应该如何实施?如果我理解正确,这应该在数据库级别完成,这是否意味着您必须根据用户(授权)组连接到数据库?阿波罗文档的第二个链接已失效。
      猜你喜欢
      • 2019-04-16
      • 2019-12-27
      • 1970-01-01
      • 1970-01-01
      • 2018-08-22
      • 1970-01-01
      • 2020-01-15
      • 2018-08-05
      • 1970-01-01
      相关资源
      最近更新 更多