【问题标题】:Architecture: managing pool of api keys架构:管理 api 密钥池
【发布时间】:2021-07-07 12:00:37
【问题描述】:

背景:

  • 我正在努力使用谷歌自己的custom search JSON API在我们的平台上启用谷歌搜索。

  • 该平台是multi-tenant 架构,每个租户可以有多个用户。

  • 每个API 键上的10K 调用有一个每日上限,因此我们计划必须集中起来以满足客户的需求。

  • 这个API会被前端代码(UI)直接调用。

寻找可能的解决方案:

  1. 在用户登录平台网站时提供从池到前端逻辑的有效密钥(请注意,用户可能使用也可能不使用嵌入式谷歌搜索,但前端应始终拥有有效密钥以防万一用户执行嵌入式谷歌搜索)。
  2. 跟踪 API 密钥的使用次数,以了解密钥何时用完其配额。
  3. 使用什么样的存储来存储这些密钥?
  4. 对租户或用户启用“速率限制”,以便每个人都能公平分享可用的通话总数。

【问题讨论】:

    标签: architecture api-key rate-limiting google-search-api


    【解决方案1】:

    首先,从安全角度来看,这种通过访问 API 密钥直接调用外部 API 的 UI 想法听起来并不好。在调用外部 API 之前,我仍然会考虑使用瘦后端层来验证请求。

    现在回答您的问题,Google API 已经有方法来monitor API usage,这是我首先会考虑的事情,因为根据您的应用程序的规模,跟踪 API 使用情况可能难以管理。

    您还可以设置API usage per user 的上限,以确保您没有达到 10K 限制,这基本上就是您要寻找的 - 如果用户达到分配的配额,则限制用户的速率。据我所知,这适用于某些 Google API,需要检查一下它是否也适用于搜索 API。

    现在,如果您有充分的理由自己做,您可以将密钥存储在快速的 No-SQL 缓存中,例如 Redis。它可能需要一些自定义逻辑来始终为您提供调用次数最少的 API 密钥,但这可以确定。

    可以使用Bucket4J 或类似的库来限制速率。

    【讨论】:

    • 如果我引入一个后端层,它会引入网络延迟,我们习惯于即时谷歌搜索结果。这会影响用户体验。
    • 当然可以,但是风险是让攻击者消耗所有密钥的全部配额,这将导致所有用户都被限速。