我有一个Web应用程序,可以从我新创建的JSON API中提取数据。
我的静态HTML页面通过JavaScript从静态HTML页面动态调用JSON API。
如何限制对我的JSON API的访问,以便只有我(我的网站)可以从它调用?
如果有帮助,我的API是这样的:http://example.com/json/?var1=x&var2=y&var3=z ...它基于查询生成适当的JSON。
我使用PHP来生成我的JSON结果。限制对JSON API的访问是否可以像检查$_SERVER['HTTP_REFERER']
一样简单,以确保仅从我的域而不是远程用户调用API?
9条答案
按热度按时间j5fpnvbx1#
我想你可能误解了JSON请求是从用户的浏览器发起的,而不是从你自己的服务器发起的。静态HTML页面被传递到用户的浏览器,然后它转向并执行页面上的JavaScript代码。这段代码打开了一个新的连接,返回到您的服务器以获取JSON数据。从PHP脚本的Angular 来看,JSON请求来自外部世界的某个地方。
鉴于上述机制,您无法阻止任何人在HTML页面的上下文之外调用JSON API。
roqulrg32#
限制对域的访问的常用方法是在内容前添加无限运行的内容。
举例来说:
因此,当您通过XMLHttpRequest或任何其他仅限于您的域的方法获取它时,您知道需要解析出无限循环。但如果是通过脚本节点获取:
它会失败,因为脚本永远不会超过第一条语句。
mznpcxlj3#
在我看来,你不能限制访问,只会让它更难。这有点像通过模糊来限制访问。引用可以很容易地伪造,即使使用短暂的键,脚本也可以通过不断刷新键来获得响应。
那么,我们能做些什么呢?
找出这里的弱点:
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页面中的所有键,但是这种类型的攻击是不同的(更容易避免的)问题。
**缺点:**当然,你不能使用这个方法来限制不依赖于键的查询,例如:搜索
hgb9j2n64#
如果使用API的静态页面需要在公共Internet上,那么这里的任何解决方案都是不完美的。由于您需要能够让客户端的浏览器发送请求并使其被接受,因此几乎任何人都可能看到您如何形成该URL。
您可以让API后面的应用程序检查HTTP转发器,但如果有人想这样做,这很容易伪造。
如果不要求页面是静态的,那么您可以尝试使用由API生成并包含在第一个页面的HTML响应中的短期“键”,该“键”作为参数传递回API。这会增加API的开销,因为你必须让服务器维护一个有效的“密钥”列表,它们的有效期等。
因此,您可以采取一些步骤,这些步骤不会花费很多,但如果有人真的想这样做,也不难实现,或者您可以花更多的时间来使它变得更难,但如果您的API必须是公共可访问的,那么就没有完美的方法来做到这一点。
cpjpxq1n5#
简短的回答是:任何人谁可以访问您的网站的页面也将能够访问您的API。
您可以尝试以各种方式加密API,使其使用更加困难,但是由于您必须包含用于解密API输出的JavaScript代码,因此您将与任何决定通过其他方式使用您的API的人进行军备竞赛。即使您使用短期密钥,一个坚定的“攻击者”也总是可以在使用API之前抓取您的HTML(沿着当前密钥)。
如果你想做的只是阻止其他网站在他们的网页上使用你的API,那么你可以使用Referrer头,但要记住,不是所有的浏览器都发送Referrer(有些代理也会剥离它们!))。这意味着您希望允许所有请求都缺少一个删除器,而这只能给予部分保护。此外,推荐人可以很容易地伪造,所以如果一些其他网站 * 真的 * 想使用您的API,他们总是可以欺骗浏览器,并从他们的服务器访问您的API。
xv8emn3q6#
您是否或是否可以使用基于cookie的身份验证?我的经验是基于ASP.NETforms身份验证,但同样的方法应该也适用于PHP,只需要一点代码。
其基本思想是,当用户通过Web应用程序进行身份验证时,将向客户端浏览器返回一个具有加密值的cookie。然后,json API将使用该cookie来验证调用者的身份。
这种方法显然需要使用Cookie,所以这对您来说可能是也可能不是问题。
tcomlyy67#
对不起,也许我错了,但是...可以使用HTTPS吗?
您可以(?)通过https://example.com/json/访问您的API?var 1 =x&var2=y,因此只有经过身份验证的消费者才能获得您的数据...
mxg2im7a8#
对不起,网络上没有DRM:-)
您不能将HTML视为受信任的客户端。这是一个纯文本脚本,在其他人的计算机上解释,因为他们认为合适。无论你允许你的“自己的”JavaScript代码,你允许任何人。你甚至不能定义多长时间它是“你的”与Greasemonkey和Firebug在野外。
您必须在服务器中复制所有访问控制和业务逻辑限制,就好像JavaScript客户机中不存在这些限制一样。
将服务包含在SSO中,限制每个用户可以访问的URL,设计服务时将wget视为客户端,而不是行为良好的JavaScript代码。
xu3bshqb9#
这不会限制物理意义上的访问,但您可以加密JSON的整个内容,并且只有具有特定关键字的特定用户才能解密。在没有物理访问限制可以可靠地实现的情况下,这可能是第二好的事情。只要我们有加密的权利。