我正在开发使用后端流行的Web框架的restful web应用程序,例如(rails,sinatra,flask,express.js)。理想情况下,我想用Backbone.js开发客户端。如何让我的javascript客户端与这些API调用进行交互?我不希望这些API调用是公开的,并且可以由curl
调用,或者只需在浏览器上输入链接即可。
答案 0 :(得分:74)
作为第一个原则,如果您的API由您的JS客户端使用,您必须假设它是公共的:一个简单的JS调试器将攻击者置于一个位置,在那里他可以发送逐字节的相同内容来自他选择的工具的请求。
那就是说,如果我正确地读了你的问题,那就不是,你想要避免的:你真正不希望发生的是,你的API被定期消费(没有你的JS客户端)参与其中。以下是关于如何不执行的一些想法,然后至少鼓励使用您的客户:
我确信,您的API具有某种身份验证字段(例如,在客户端上计算的哈希值)。如果没有,请查看This SO question。确保使用基于会话(a.o.t.硬编码)给予JS客户端的salt(甚至API密钥)。这样,您的API的未经授权的消费者就被迫做更多的工作。
在加载JS客户端时,请记住一些HTTP标头(用户代理人会想到)和IP地址,如果他们发生变化则要求重新认证,并为常见的嫌疑人使用黑名单。这迫使攻击者再次彻底地完成他的作业。
在服务器端,记住最后几个API调用,在允许另一个API调用之前,检查业务逻辑是否允许新的调用:这会使攻击者无法将他的许多会话集中到一个与您的服务器会话:结合其他措施,这将使滥用者易于检测。
我可能没有说清楚:我认为不可能让施虐者完全无法使用你的服务,但是你可以这么做,它可能不是值得麻烦。
答案 1 :(得分:10)
您应该实现某种身份验证系统。处理此问题的一种好方法是定义一些预期的标头变量。例如,您可以使用auth / login API调用来返回会话令牌。对API的后续调用将期望在HTTP标头变量中设置会话令牌,该变量具有特定名称,如“your-api-token”。
或者,许多系统使用某种api帐户系统创建预期的访问令牌或密钥(如youtube,facebook或twitter)。在这些情况下,您的客户必须以某种方式将这些存储在客户端中。
然后,只需将会话检查添加到REST框架并抛出异常即可。如果可能的话,状态代码(要休息)将是401错误。
答案 2 :(得分:6)
现在有一个开放的标准叫做#34; JSON Web Token",
见https://jwt.io/& https://en.wikipedia.org/wiki/JSON_Web_Token
JSON Web Token(JWT)是一个基于JSON的开放标准(RFC 7519) 创建表示一些索赔的令牌。例如,a 服务器可以生成具有声明的令牌"以管理员身份登录" 并将其提供给客户。然后客户端可以使用该令牌 证明他们以管理员身份登录。令牌由签名 服务器的密钥,因此服务器能够验证令牌是否 合法。令牌设计紧凑,URL安全且可用 特别是在Web浏览器单点登录(SSO)上下文中。 JWT声称可以 通常用于在一个之间传递经过身份验证的用户的身份 身份提供者和服务提供者,或任何其他类型的声明 根据业务流程的要求。[1] [2]令牌也可以 经过身份验证和加密。[3] [4]
答案 3 :(得分:3)
对不起@MarkAmery和Eugene,但那不对。
您在浏览器中运行的js + html(客户端)应用可以设置为排除未经授权的直接调用API,如下所示:
- 第一步:设置API以要求身份验证。 客户端必须首先通过服务器(或其他安全服务器)验证自身,例如要求人类用户提供正确的密码。
醇>在验证之前,不接受对API的调用。
在身份验证期间,返回“令牌”。
在身份验证之后,只接受带有身份验证“令牌”的API调用。
当然,在此阶段,只有拥有密码的授权用户才能访问API,但如果他们是程序员调试应用程序,他们可以直接访问它以进行测试。
现在,为了使用您的API,他们必须首先下载客户端并实际在浏览器中运行它。只有在成功接收回调,然后在短时间内进行用户输入后,API才会接受呼叫。
因此,您不必担心这可能是没有凭据的未经授权的用户。
(问题的标题,'如何保护REST API调用',以及您所说的大部分内容,这是您主要关注的问题,而不是您的API调用的字面问题,而是BY WH WHOM ,对吗?)
答案 4 :(得分:0)
当客户端首次加载index.html
(或backbone.js
等)时,在服务器上设置SESSION var
在每次API调用时检查服务器端的var。
P.S。这不是一个“安全”的解决方案!这只是为了减轻您服务器的负担,因此人们不会滥用它或将您的API与其他网站和应用程序“热链接”。
答案 5 :(得分:0)
这就是我要做的:
使用诸如X-APITOKEN之类的调用的HTTP标头来保护API:
在PHP中使用会话变量。有一个登录系统,并将用户令牌保存在会话变量中。
使用Ajax将JS代码调用到PHP,并使用带有curl的session变量来调用API。这样,如果未设置会话变量,则不会调用它,并且PHP代码包含对API的访问令牌。