103

我正在开发一个在后端使用一些流行的 web 框架的 restful web 应用程序,比如(rails、sinatra、flask、express.js)。理想情况下,我想用 Backbone.js 开发客户端。如何只让我的 javascript 客户端与这些 API 调用交互?我不希望这些 API 调用是公开的,并且不希望curl通过在浏览器上输入链接来调用或简单地调用。

4

6 回答 6

101

作为第一个原则,如果你的 API 被你的 JS 客户端使用,你必须假设它是公开的:一个简单的 JS 调试器将攻击者置于一个位置,在那里他可以从他选择的工具。

也就是说,如果我正确阅读了您的问题,这不是您想要避免的:您真正不希望发生的是,您的 API 被使用(定期)而没有涉及您的 JS 客户端。以下是一些关于如果不强制执行的想法,那么至少鼓励使用您的客户端:

  • 我敢肯定,您的 API 有某种身份验证字段(例如在客户端计算的哈希)。如果没有,请查看This SO question确保使用基于会话(aot 硬编码)提供给 JS 客户端的盐(甚至 API 密钥)。这样一来,未经授权的 API 使用者就会被迫做更多的工作。

  • 在加载 JS 客户端时,请记住一些 HTTP 标头(想到用户代理)和 IP 地址,并在它们发生变化时要求重新验证,为通常的嫌疑人使用黑名单。这迫使攻击者再次更彻底地完成作业。

  • 在服务器端,记住最后几个 API 调用,在允许另一个 API 调用之前,检查业务逻辑现在是否允许新的调用:这使攻击者无法将他的许多会话集中到与您的服务器的一个会话中:结合其他措施,这将使施虐者很容易被发现。

我可能没有说得那么清楚:我认为不可能让施虐者完全不可能消费你的服务,但你可以让它变得如此困难,这可能不值得麻烦。

于 2012-12-15T20:15:22.433 回答
12

您应该实施某种身份验证系统。处理此问题的一种好方法是定义一些预期的标头变量。例如,您可以有一个返回会话令牌的 auth/login API 调用。对您的 API 的后续调用将期望在 HTTP 标头变量中设置一个会话令牌,该变量具有特定名称,例如“your-api-token”。

或者,许多系统使用某种 api 帐户系统创建预期的访问令牌或密钥(如 youtube、facebook 或 twitter)。在这些情况下,您的客户必须以某种方式将这些存储在客户端中。

然后只需将会话检查添加到您的 REST 框架并引发异常即可。如果可能的话,状态码(要安静)将是 401 错误。

于 2012-12-15T20:17:39.567 回答
8

现在有一个开放标准称为“JSON Web Token”,

https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token

JSON Web Token (JWT) 是一种基于 JSON 的开放标准 (RFC 7519),用于创建声明一些声明的令牌。例如,服务器可以生成具有“以管理员身份登录”声明的令牌并将其提供给客户端。然后,客户端可以使用该令牌来证明他们以管理员身份登录。令牌由服务器的密钥签名,因此服务器能够验证令牌是否合法。这些令牌被设计为紧凑、URL 安全和可用,尤其是在 Web 浏览器单点登录 (SSO) 上下文中。JWT 声明通常可用于在身份提供者和服务提供者之间传递经过身份验证的用户的身份,或业务流程所需的任何其他类型的声明。[1][2] 令牌也可以进行身份​​验证和加密。[3][4]

于 2016-07-27T08:57:31.103 回答
1

对不起@MarkAmery 和 Eugene,但这是不正确的。

您在浏览器中运行的 js+html(客户端)应用程序可以设置为排除对 API 的未经授权的直接调用,如下所示:

  1. 第一步:设置 API 以要求身份验证。客户端必须首先通过服务器(或其他一些安全服务器)对自己进行身份验证,例如要求人类用户提供正确的密码。

在进行身份验证之前,不接受对 API 的调用。

在身份验证期间,会返回一个“令牌”。

身份验证后,仅接受带有身份验证“令牌”的 API 调用。

当然在这个阶段只有拥有密码的授权用户才能访问API,尽管如果他们是调试应用程序的程序员,他们可以直接访问它进行测试。

  1. 第二步:现在设置一个额外的安全 API,在客户端 js+html 应用程序最初从服务器请求后的短时间内调用。这个“回调”会告诉服务器客户端下载成功。仅当最近成功请求客户端时才限制您的 REST API 调用。

现在,为了使用您的 API,他们必须首先下载客户端并在浏览器中实际运行它。只有在成功接收到回调,并在短时间内用户进入后,API才会接受调用。

因此,您不必担心这可能是没有凭据的未经授权的用户。

(问题的标题是“我如何保护 REST API 调用”,从你所说的大部分内容来看,这是你主要关心的问题,而不是如何调用你的 API 的字面问题,而是由谁来调用,对吗? )

于 2015-11-12T14:58:34.870 回答
1
  1. 当客户端首次加载您的index.html(或backbone.js等)时,在服务器上设置一个 SESSION var

  2. 在每次 API 调用时在服务器端检查这个 var。

PS这不是一个“安全”解决方案!!!这只是为了减轻服务器上的负载,这样人们就不会滥用它或从其他网站和应用程序“热链接”您的 API。

于 2018-01-30T14:50:10.353 回答
0

这就是我所做的:

  1. 使用 X-APITOKEN 等调用使用 HTTP 标头保护 API:

  2. 在 PHP 中使用会话变量。有一个登录系统并将用户令牌保存在会话变量中。

  3. 使用 Ajax 调用 JS 代码到 PHP 并使用带有 curl 的 session 变量调用 API。这样,如果会话变量未设置,它将不会调用并且 PHP 代码包含 API 的访问令牌。

于 2018-07-23T07:32:51.650 回答