Php 如何限制JSON访问?

Php 如何限制JSON访问?,php,json,api,rest,Php,Json,Api,Rest,我有一个web应用程序,它从我新创建的JSON API中提取数据 我的静态HTML页面通过JavaScript从静态HTML页面动态调用JSON API 如何限制对JSON API的访问,以便只有我(我的网站)可以从中调用? 如果有帮助,我的API类似于:。。。它根据查询生成相应的JSON 我正在使用PHP生成JSON结果。。。限制对JSON API的访问是否可以像检查$\u服务器['HTTP\u REFERER']一样简单,以确保仅从我的域而不是远程用户调用该API?如果使用该API的静态页面

我有一个web应用程序,它从我新创建的JSON API中提取数据

我的静态HTML页面通过JavaScript从静态HTML页面动态调用JSON API

如何限制对JSON API的访问,以便只有我(我的网站)可以从中调用?

如果有帮助,我的API类似于:。。。它根据查询生成相应的JSON


我正在使用PHP生成JSON结果。。。限制对JSON API的访问是否可以像检查
$\u服务器['HTTP\u REFERER']
一样简单,以确保仅从我的域而不是远程用户调用该API?

如果使用该API的静态页面需要位于公共Internet上,则此处的任何解决方案都将是不完善的。由于您需要能够让客户端的浏览器发送请求,并让请求得到满足,因此几乎所有人都可以看到您是如何形成该URL的

你可以让API后面的应用程序检查http引用程序,但如果有人想要,这很容易伪造

如果页面不要求是静态的,您可以尝试使用API生成的短期“键”并包含在第一个页面的HTML响应中,该响应作为参数传递回API。这会增加API的开销,因为您必须让服务器维护一个有效的“密钥”列表,以及它们的有效期等


因此,如果有人真的想要,您可以采取一些成本不高但不难实现的步骤,或者您可以花更多的时间使其变得更加困难,但如果您的API必须公开访问,则没有完美的方法来实现这一点

简单的回答是:任何可以访问您网站页面的人都可以访问您的API

您可以尝试通过各种方式对API进行加密,从而使使用API变得更加困难,但由于您必须包含JavaScript代码来解密API的输出,因此您将与任何决定通过其他方式使用API的人展开军备竞赛。即使您使用的是短期密钥,一个坚定的“攻击者”也可能在使用API之前就删除您的HTML(以及当前密钥)


如果您只想阻止其他网站在其网页上使用您的API,那么您可以使用referer头,但请记住,并非所有浏览器都发送referer(有些代理也会删除它们!)。这意味着您希望允许所有请求都缺少一个推荐人,这只会给您部分保护。此外,引用者很容易伪造,因此如果其他网站真的想使用你的API,他们总是可以欺骗浏览器并从他们的服务器访问你的API。

限制访问你的域的常用方法是在内容前面加上无限运行的东西

例如:

while(1);{"json": "here"} // google uses this method
for (;;);{"json": "here"} // facebook uses this method
因此,当您通过XMLHttpRequest或任何其他仅限于您的域的方法获取此文件时,您知道需要解析出无限循环。但如果是通过脚本节点获取的:

<script src="http://some.server/secret_api?..."></script>


它将失败,因为脚本永远不会超出第一条语句。

我认为您可能误解了JSON请求是从用户浏览器而不是从您自己的服务器启动的部分。静态HTML页面被传递到用户的浏览器,然后它会翻转并执行页面上的Javascript代码。这段代码打开一个新的连接返回到您的服务器以获取JSON数据。从PHP脚本的角度来看,JSON请求来自外部世界的某个地方


考虑到上述机制,您无法阻止任何人在HTML页面的上下文之外调用JSON API。

在我看来,您不能限制访问,只能让访问更加困难。这有点像晦涩难懂的访问限制。引用者很容易被伪造,即使使用了短暂的密钥,脚本也可以通过不断刷新密钥来获得响应

那么,我们能做些什么呢

在这里找出弱点:

攻击者现在可以在一个循环中轻松请求1到1.000.000之间的所有用户信息。
auto_increment
IDs的弱点在于它们的线性度,并且容易猜测

解决方案:为数据使用非数字唯一标识符

你不能在上面绕圈子。诚然,您仍然可以为所有类型的键解析HTML页面中的键,但是这种类型的攻击是不同的(并且更容易避免)问题


缺点:当然,您不能使用此方法限制不依赖于键的查询,例如搜索。

对不起,也许我错了,但是。。。可以使用HTTPS进行吗


您可以(?)通过https://example.com/json/?var1=x&var2=y访问您的API,因此只有经过身份验证的消费者才能获取您的数据……

是您,还是您可以使用基于cookie的身份验证?我的经验是基于ASP.NET表单身份验证的,但同样的方法应该适用于PHP,只需少量代码

其基本思想是,当用户通过web应用程序进行身份验证时,具有加密值的cookie将返回到客户端浏览器。json api随后将使用该cookie来验证调用方的身份


这种方法显然需要使用Cookie,因此这对您来说可能是问题,也可能不是问题。

对不起,web上没有DRM:-)

不能将HTML视为受信任的客户端。这是一个纯文本脚本,在其他人的计算机上按他们认为合适的方式进行解释。无论您允许“自己的”JavaScript代码做什么,您都允许任何人。你甚至无法定义它在野外的“属于你”的时间

您必须复制服务器中的所有访问控制和业务逻辑限制,就像JavaScript客户端中不存在这些限制一样