GraphQL:如何防止数据库刮取?
假设我在GraphQL:如何防止数据库刮取?,graphql,apollo,Graphql,Apollo,假设我在https://api.service.com/graphql用于在https://www.service.com+iOS应用程序+安卓应用程序。我想向公众公开这个API,这样第三方应用程序就可以通过查询数据在上面构建,但是我不希望他们能够刮伤我的整个数据库 假设我们有一种类型: type Thing { # public fields field1: String field2: String # fields only available in the offici
https://api.service.com/graphql
用于在https://www.service.com
+iOS应用程序+安卓应用程序。我想向公众公开这个API,这样第三方应用程序就可以通过查询数据在上面构建,但是我不希望他们能够刮伤我的整个数据库
假设我们有一种类型:
type Thing {
# public fields
field1: String
field2: String
# fields only available in the official UI
field3: String
field4: String
}
和一个查询:
{
things(limit: Int!, offset: Int): [Thing]
}
什么是只允许公司的官方用户界面查询所有内容
字段并循环所有内容的最佳方式?应该只允许第三方开发人员在每件事情上查询field1
和field2
,并且对他们可以访问多少事情有一些限制
选择1
我考虑要求每个客户机在每个查询请求中都包含一个令牌,这样就可以检测到官方网站、iOS应用程序和Android应用程序并将其列入“白名单”。但是,如果您的javascript/应用程序包存储在客户端上,那么有什么可以阻止某人深入您的javascript/应用程序包并找到所述令牌呢
选择2
我考虑发布两个具有两个不同模式/限制集的不同API端点,例如:
https://api.service.com/graphql
-公开记录并使用有限的模式
https://api.service.com/graphql-anon
-由官方用户界面私人使用,并包含一个功能齐全/不受限制的模式
但是,还有什么能阻止用户询问应用程序包并发现
https://api.service.com/graphql-anon
端点存在并使用它来替代?首先,我要提出一个旁白:我通常主张为您的公共API使用一个单独的模式和端点,原因有很多:
- 清除文档。共享架构意味着某些字段或参数将无法访问,或者在使用时会抛出错误,这在查看GraphiQL/GraphQL或自省架构时可能不太明显
- 更干净的代码。您的解析器几乎没有那么多分支逻辑,这将使它们更易于阅读和测试
- 隐藏差异。您为“内部”API实现的功能(如缓存或分析)可能对您的公共API没有意义(并且可能会不必要地增加维护端点的成本)
- 速率限制。您需要对公共API实施某种速率限制。如果有单独的端点,这可能会更容易做到
- 客户端使用用户的凭据调用某个登录端点,并返回身份验证流
- 该令牌由客户端临时保存,并随后续每个请求一起发送到API
- 当用户注销时,令牌将被删除
在公共API的情况下,您可以以类似的方式使用一些客户机令牌组合来识别第三方客户机(例如,他们可能不必登录,但使用令牌散列和注册时分配给他们的秘密)。如果您有一个共享模式,则可以支持这两种身份验证机制。这样,“第三方客户机”就可以是另一个角色,可以访问某些字段子集。首先,我要说的是:我通常主张为公共API提供一个单独的模式和端点,原因有很多:
- 清除文档。共享架构意味着某些字段或参数将无法访问,或者在使用时会抛出错误,这在查看GraphiQL/GraphQL或自省架构时可能不太明显
- 更干净的代码。您的解析器几乎没有那么多分支逻辑,这将使它们更易于阅读和测试
- 隐藏差异。您为“内部”API实现的功能(如缓存或分析)可能对您的公共API没有意义(并且可能会不必要地增加维护端点的成本)
- 速率限制。您需要对公共API实施某种速率限制。如果有单独的端点,这可能会更容易做到