fullstack GraphQL 学习笔记(8)安全
由于客户端可以编写非常复杂的查询,因此我们的服务器必须准备好正确处理它们。这些查询可能是来自恶意客户端的滥用查询,或者可能只是合法客户端使用的非常大的查询。在这两种情况下,客户端都可能会关闭您的GraphQL服务器。
有一些策略可以缓解这些风险,我们将在本章中介绍这些策略。我们将按照最简单到最复杂的顺序覆盖它们,并查看它们的优缺点。
1、Timeout
超时优点
- 易于实施。
- 大多数策略仍将使用超时作为最终保护。
超时缺点
- 即使超时开始,也可以完成损坏。
- 有时难以实施。在一定时间后切断连接可能会导致奇怪的行为。
2、Maximum Query Depth
通过分析查询文档的抽象语法树(AST),GraphQL服务器能够根据其深度拒绝或接受请求。
最大查询深度优点
- 由于文档的AST是静态分析的,因此查询甚至不会执行,这会增加GraphQL服务器的负载。
最大查询深度缺点
- 仅靠深度通常不足以涵盖所有滥用查询。例如,在根上请求大量节点的查询将非常昂贵,但不太可能被查询深度分析器阻止。
3、Query Complexity
查询复杂性允许您定义这些字段的复杂程度,并限制查询的最大复杂性。我们的想法是使用一个简单的数字来定义每个字段的复杂程度。一个常见的默认设置是为每个字段提供复杂性1。以此查询为例:
query {
author(id: "abc") { # complexity: 1
posts { # complexity: 1
title # complexity: 1
}
}
}
一个简单的添加为我们3提供了这个查询的复杂性。如果我们要在schema上设置最大复杂度2,则此查询将失败。
如果posts实际上比author复杂得多怎么办?我们可以为该领域设置不同的复杂性。我们甚至可以根据参数设置不同的复杂性!让我们看看一个类似的查询,其中posts根据其参数具有可变的复杂性:
query {
author(id: "abc") { # complexity: 1
posts(first: 5) { # complexity: 5
title # complexity: 1
}
}
}
查询复杂性优点
- 涵盖的案例多于简单的查询深度。
- 通过静态分析复杂性,在执行查询之前拒绝查询。
查询复杂性缺点
- 难以完美实施。
- 如果开发人员估计复杂性,我们如何使其保持最新?我们如何首先找到成本?
- 突变很难估计。如果他们有副作用很难衡量,如排队后台工作怎么办?
4、Throttling
基于服务器时间的限制
很好地估计查询的成本是它需要完成的服务器时间。我们可以使用此启发式来限制查询。通过对系统的充分了解,您可以获得客户端在特定时间范围内可以使用的最长服务器时间。
我们还决定随着时间的推移向客户端添加多少服务器时间。这是一种经典的漏桶算法。请注意,还有其他限制算法,但它们超出了本章的范围。
基于查询复杂度的限制
总结:
GraphQL非常适合客户端使用,因为它为它们提供了更多功能。但是这种能力也使他们有可能滥用你的GraphQL服务器和非常昂贵的查询。
浙公网安备 33010602011771号