如何限制JSON访问?

时间:2009-05-13 04:19:23

标签: php json api rest

我有一个Web应用程序,可以从我新创建的JSON API中提取数据。

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

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

如果有帮助,我的API类似于:http://example.com/json/?var1=x&var2=y&var3=z ...根据查询生成适当的JSON。

我正在使用PHP生成我的JSON结果...可以限制对JSON API的访问,就像检查$_SERVER['HTTP_REFERER']一样简单,以确保只从我的域而不是远程调用API用户?

8 个答案:

答案 0 :(得分:18)

限制对您的域的访问的常用方法是在内容之前添加无限运行的内容。

例如:

while(1);{"json": "here"} // google uses this method
for (;;);{"json": "here"} // facebook uses this method

因此,当您通过XMLHttpRequest或仅限于您的域的任何其他方法获取此内容时,您知道需要解析无限循环。但是如果它是通过脚本节点获取的:

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

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

答案 1 :(得分:17)

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

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

答案 2 :(得分:5)

在我看来,你不能限制访问权限,只会让它变得更难。这有点像默默无闻的访问限制。引用者可以很容易伪造,即使使用短期密钥,脚本也可以通过不断刷新密钥来获得响应。

那么,可以我们做什么?

找出这里的弱点:

  

http://www.example.com/json/getUserInfo.php?id=443

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

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

  

http://www.example.com/json/getUserInfo.php?userid=XijjP4ow

你无法绕过那些。没错,您仍然可以解析HTML页面中各种键的键,但这种类型的攻击是不同的(也更容易避免)问题。

下行当然,您无法使用此方法来限制与密钥无关的查询,例如:搜索范围。

答案 3 :(得分:4)

如果使用API​​的静态页面需要在公共Internet上,那么此处的任何解决方案都将是不完美的。由于您需要能够让客户端的浏览器发送请求并使其受到尊重,因此几乎任何人都可以确切了解您是如何形成该URL的。

您可以让API后面的应用检查http引用,但如果有人愿意,这很容易伪造。

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

所以,你可以采取一些步骤,这些步骤不会花费很多,但如果有人真的想要,也不难解决,或者你可以花更多的时间让它变得更难,但是没有完美的如果您的API必须可公开访问,请执行此操作。

答案 4 :(得分:4)

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

您可以尝试通过各种方式对API进行加密来使用API​​变得更加困难,但由于您必须包含用于解密API输出的JavaScript代码,因此您只需设置自己的API即可。与决定他们想通过其他方式使用您的API的任何人进行军备竞赛。即使您使用短期密钥,确定的“攻击者”也可能只是在使用API​​之前抓取您的HTML(以及当前密钥)。

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

答案 5 :(得分:0)

抱歉,也许我错了,但是......可以使用HTTPS制作吗?

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

答案 6 :(得分:0)

您是,还是可以使用基于cookie的身份验证?我的经验是基于ASP.NET表单身份验证,但使用PHP代码时,相同的方法应该是可行的。

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

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

答案 7 :(得分:0)

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

您不能将HTML视为受信任的客户端。它是一个纯文本脚本,在他们认为合适的情况下在其他人的计算机上进行解释。无论你允许“自己的”JavaScript代码,你都允许任何人。你甚至无法用野外的GreasemonkeyFirebug来定义它的“你的”。

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

在SSO中加入服务,限制每个用户有权访问的网址,设计服务时将wget保留为客户端,而不是表现良好的JavaScript代码。