【发布时间】:2011-03-10 16:45:12
【问题描述】:
我正在尝试编写一些各种网站将嵌入的代码,并在我的服务器上调用脚本。该脚本流式传输图像的二进制数据并将其吐出到图像标签中。
但是,我正在尝试控制谁可以访问该脚本。因此,如果我将嵌入代码分发给 yourwebsite.com,我想确保请求此脚本的客户端是从“yourwebsite.com”获取的。
有什么建议吗?
【问题讨论】:
我正在尝试编写一些各种网站将嵌入的代码,并在我的服务器上调用脚本。该脚本流式传输图像的二进制数据并将其吐出到图像标签中。
但是,我正在尝试控制谁可以访问该脚本。因此,如果我将嵌入代码分发给 yourwebsite.com,我想确保请求此脚本的客户端是从“yourwebsite.com”获取的。
有什么建议吗?
【问题讨论】:
最简单的方法是查看推荐人$_SERVER['HTTP_REFERER']。但这可能是伪造的。
更安全的是使用某种授权,即
您为允许查看此图片的每个客户提供一个唯一的密钥(或盐)。
然后您的客户必须创建一个标准化的时间字符串,例如20100701170821。
然后你的客户可以做这样的事情:
<?php
$public_identifier = "yourclient.com";
$secret = "1234567890ABCDFGHIJKLMNOPQRSTUVWXYZ";
$time_string = date("YmdHis");
$signature = hash_hmac('sha256',$time_string,$secret)
$url_to_access_the_images += "?time=$timestring&signature=$signature&client_id=$public_identifier"
?>
这将生成一个这样的 URL:
yourdomain.com/secret_image.php?time=20100701170821&signature=e9de9112433944188b5da9fa7157bf167bfdd6af95120aea2674424838154ea9&client_id=yourclient.com
在您的网站上,您可以像这样进行检查:
<?php
$secret = get_secret_for_client_id($_GET['client_id']);
// check if the request time is within a tolerance of 15 minute
// time difference between client server and your server
// and check if he's authorized (signature is valid).
if(abs(int($_GET['time']) - int(date("YmdHis"))) < 1500) &&
$_GET['signature'] == hash_hmac('sha256',$_GET['time'],$secret)) {
// do what ever you do to ouput the picture
} else {
// do what ever you do for unauthorized access.
}
?>
【讨论】:
我宁愿使用
$_SERVER['REMOTE_ADDR'];
而不是容易欺骗的REFERER。您可能必须为一个客户端分配多个 IP,但这应该不是问题。
如果您不想使用服务器变量,只需分发 API 密钥并让他们在每次请求时将其提交到您的服务脚本。
【讨论】:
<img src="example.com/image.php"/> 的事情,而他在使用inline data URLs 时无法做到。
你试过$_SERVER['HTTP_REFERER']吗?
这在大多数情况下都会起作用,但请考虑以下情况:
REFERER 是由客户端的浏览器作为 HTTP 协议的一部分发送的,因此确实不可靠。它可能不存在,它可能是伪造的,如果出于安全原因,您就不能信任它。
如果您想验证请求是否来自您的站点,那么您不能,但您可以验证用户是否曾访问过您的站点和/或已通过身份验证。 Cookie 在 AJAX 请求中发送,因此您可以依赖它。
通过@Seldaek
【讨论】:
【讨论】: