提供公共内容时如何保护 REST API 不被抓取?

信息安全 加密 Web应用程序 javascript 休息
2021-09-07 10:07:07

我有一个 ReactJs 网络应用程序,一个 Android 应用程序,它都使用用 django 构建的 REST API,整个项目用于媒体/新闻,REST API 的最大部分是公共内容,有一小部分用户有安全 API具有基于令牌的身份验证的端点。

我们面临的问题是,有更多的人在爬取我们的 REST API 并在许多地方复制我们的内容,而我们无法跟踪并阻止它们,因此我们正在考虑一些方法来制作 REST API更难被爬行。

我目前建议的解决方案:加密,但我目前对加密的理解是,你加密来自服务器的 REST API 响应,然后在客户端用 javascript 解密它,但你仍然需要解密密钥或令牌,所以你将面临其他在客户端保存该令牌的问题。

有没有比加密更好的保护 api 的方法?

在客户端保存令牌的最佳实践是什么?

谢谢。

2个回答

我曾经以编写网络抓取工具为工作,这是我在处理您的问题时遇到的最棘手问题的两分钱。

  1. 通过多个 AJAX 调用加载部分或全部内容。如果刮板不适合您的网站,这将停止刮板。在实践中,您可以使用仅具有内容开头的 JSON 和将被请求获取内容的下一部分的 nonce 令牌来回答。

  2. 此外,如果您知道您的 REST api 只应在您的 React 应用程序中使用,您可以将来自 Django 的长时间令牌添加到主 React 模板。然后 REST API 将需要内容 ID 以及该唯一令牌。在您的数据库中,您可以将该令牌分配给给定的 IP 地址,并使其在相当短的时间内过期。这将要求机器人首先获取应用程序的 HTML 端以获取该令牌,然后再获取内容本身。

  3. 节流通常是一种烦恼。我遇到的实现是基于 IP 地址的,每秒允许用户 10 个请求。这比一个典型的人类会做的要多得多。为了通过它,我的代码必须跟踪发送十个请求的时间,然后在超时请求时再发送十个内容。

  4. 将蜜罐添加到disallow您的robots.txt. 邪恶的机器人不遵守规则。同样是同一工作的一部分,我们将重新分发内容并让其他人尝试抓取它。这是阻止大多数机器人的最有效方法:允许它们对蜜罐进行 3 次点击,然后将它们列入黑名单 36 小时,除非它们成功解决了验证码(我们为此使用了外部工具)。对于 Django 集成,我们将其编码为中间件,因此它适用于所有页面。为了使性能问题最小化,我们使用 Django 的缓存来存储哪些 IP 被列入黑名单或白名单(如果他们成功解决了验证码,则会将其中一个添加到白名单中)。

阻止其他人抓取您的公共网站/API 是一个难题。

您可以尝试限制和阻止向 REST API 发出过多快速请求的客户端 IP。这可以阻止那些使用简单方法来抓取您的 REST API 的人,但它不会帮助您使用使用更高级技术的爬虫 - 我不确定您的具体情况是什么。

此外,像https://www.cloudflare.com/这样的服务可以提供针对数据抓取/网络爬取的保护,您可以轻松地实施这些保护,作为解决问题的快速尝试。