狗粮我们自己的限速API

2022-08-30 05:18:40

概述:

我的公司开发了一个速率有限的 API。我们的目标有两个方面:

  • 答:围绕我们的产品创建一个强大的开发人员生态系统。
  • B:通过使用 API 来驱动我们自己的应用程序,来演示 API 的强大功能。

澄清:为什么要限制速率?

我们限制了我们的API,因为我们将其作为我们产品的补充进行销售。匿名访问我们的API的每小时API调用阈值非常低,而我们的付费客户每小时最多允许1000次或更多次调用。

问题:

我们的限速API对开发者生态系统来说非常棒,但是为了让我们对它进行狗粮,我们不能允许它被限制在相同的速率限制范围内。我们API的前端都是JavaScript,直接调用API的Ajax。

所以问题是:

如何保护 API,以便在删除此类速率限制的过程中无法轻易欺骗时删除速率限制?

探索的解决方案(以及它们不起作用的原因)

  1. 根据主机标头验证引荐来源网址。- 有缺陷,因为引用很容易伪造。

  2. 使用 HMAC 根据请求和共享机密创建签名,然后在服务器上验证请求。- 有缺陷,因为通过查看前端JavaScript可以很容易地确定秘密和算法。

  3. 代理请求并在代理中对请求进行签名 - 仍然存在缺陷,因为代理本身公开了API。

问题:

我期待Stack Overflow上的聪明才智提出替代解决方案。您将如何解决这个问题?


答案 1

由于你自己的JavaScript客户端直接访问API,任何人都可以查看它正在做什么并模仿它,包括使用相同的API密钥。你可以尝试让它变得更加困难,比如通过混淆你的代码或设置各种障碍,但你和你试图限制的人基本上具有相同的访问权限。与其试图在权限上创造差异,不如构建一个系统,在这个系统中,非官方客户端使用其范围内的所有访问权限是完全可以的,但是系统的安排方式是所有客户端的官方使用量更大。

这通常是使用每用户访问令牌完成的,而不是整个应用程序的一个令牌。每个令牌的限制对于 API 的典型使用应该足够大,但对于试图滥用它的人来说应该是限制性的。例如,每分钟100个电话可能足以支持典型的浏览,但是如果我想抓取你,我无法在预算范围内有效地做到这一点。

总会有一场军备竞赛 - 我可以通过创建大量机器人用户帐户来绕过限制。但是,如果您只是在注册流程中添加验证码,那么这是一个非常解决的问题,而对真正的人类来说却是一点点费用。当您进入这些场景时,一切都只是在便利性和限制之间进行权衡。你永远不会找到完全防弹的东西,所以专注于让它足够好,等到有人利用你来了解漏洞在哪里。


答案 2

如果这给你带来了问题,它将导致你假定的开发人员生态系统出现问题(例如,当他们尝试开发替代UI时)。如果你真的在吃自己的狗粮,让API(和速率限制)适用于你的应用。以下是一些建议:

  • 不要按 IP 地址进行速率限制。相反,通过与用户关联的内容(例如其用户 ID)进行速率限制。在身份验证阶段应用速率限制。

  • 设计您的API,以便用户不需要连续调用它(例如,给出返回许多结果的列表调用,而不是每次返回一个项目的重复调用)

  • 使用与开发人员生态系统相同的约束来设计 Web 应用,即确保可以在合理的限制速率内设计它。

  • 确保后端是可缩放的(最好是水平方向),这样就不需要在如此低的级别上施加限制,以至于实际上会导致 UI 出现问题。

  • 确保您的限制能够应对突发事件,并限制长期滥用。

  • 确保限制执行针对要删除的滥用行为量身定制的合理操作。例如,考虑排队或延迟轻度虐待者,而不是拒绝连接。大多数 Web 前端一次只能同时打开四个连接。如果您延迟尝试打开第五个,则只会遇到他们与Web客户端(ot两个Web客户端)同时使用CLI的情况。如果您延迟第n个API调用而没有间隙而不是失败,最终用户将看到事情变慢而不是中断。如果您一次只对 N 个 API 调用进行排队,则只会遇到并行处理大量 API 调用的人,这可能不是您想要的行为 - 例如,100 个并发 API 调用,那么一个小时的间隔通常比一小时内的 100 个连续 API 调用差得多。

这难道没有回答你的问题吗?好吧,如果您确实需要按照自己的要求执行操作,请在身份验证阶段进行速率限制,并根据用户适合的组应用不同的速率限制。如果使用一组凭据(由开发人员和 QA 团队使用),则会获得更高的速率限制。但是你可以立即明白为什么这将不可避免地导致你进入你的生态系统,看到你的开发和QA团队没有看到的问题。