【发布时间】:2017-08-15 07:41:59
【问题描述】:
我需要只允许通过 Ajax 和 Cron 调用 php 脚本,而不是通过它在浏览器中的地址调用。
在F12中所有的php脚本都是可见的,任何用户都可以像website.com/file.php这样调用php脚本
【问题讨论】:
-
我的问题没有答案。我需要允许 Ajax 和 Cron 访问这些文件
我需要只允许通过 Ajax 和 Cron 调用 php 脚本,而不是通过它在浏览器中的地址调用。
在F12中所有的php脚本都是可见的,任何用户都可以像website.com/file.php这样调用php脚本
【问题讨论】:
你不能。脚本不知道它们是如何被调用的;他们只知道 Web 服务器调用了它们。
并且网络服务器不知道是谁在调用,只是请求来自 HTTP 或 HTTPS 端口(cron CLI 是一个例外,见下文)。
你能做的最好的就是验证这两个标题:
HTTP_USER_AGENT either empty or filled
HTTP_X_REQUESTED_WITH either 'XMLHttpRequest' or not (possibly empty)
结果将是:
UA empty, XRW empty cron or a browser faking cron
UA "Lynx" or "wget", XRW empty cron calling wget or lynx (or curl?)
UA empty, XRW filled some prankster messing with you (*)
UA filled, XRW filled AJAX call
UA filled, XRW empty browser
(*) 或某些“隐私”客户端防火墙删除 User-Agent 标头
但请记住:
curl)你最好检查一下例如
HTTP_REMOTE_ADDR
通过cron CLI调用时没有设置,设置后应该是你授权的服务器的IP地址,如Web服务器所见。
另一种可能性是使用身份验证,例如通过在调用脚本和被调用 PHP 程序之间共享秘密的挑战/响应。
我在这里很着急,想象你的情况是这样的:
您有一个脚本需要定期调用,或者当用户通过 AJAX 执行某些操作时调用,但不要太频繁(可能是因为它的计算成本很高)。因此,您每天一次从 cron 调用脚本,并且每当某个用户查看页面时,但不希望用户看到调用并能够随意复制它,甚至可能来自不同的浏览器或他们的 cron拥有。
一个简单的解决方案是反其道而行之。您可以在会话中设置一个变量:
// AJAX calls are only allowed every 600 seconds PER EACH USER
// (you should verify that a login exists)
if (array_key_exists('ajax', $_SESSION)) {
if (time() - $_SESSION['ajax'] < 600) {
return;
}
}
$_SESSION['ajax'] = time();
或者您可以使用文件来限制调用:
if (file_exists('call.txt')) {
if ((time() - filemtime('call.txt')) < 600) {
return;
}
}
touch('call.txt');
现在,无论如何调用脚本的频率不能超过每 600 秒(10 分钟)一次(cron CLI 除外,它几乎肯定会在不同的目录中创建 call.txt)。
您也许还可以将脚本输出存储在文件中,并在文件不早于给定值时读取文件的内容。所以你可以发出一千个 AJAX 调用,但只有第一个会做任何实际的工作——另一个会等待锁定的文件,然后读取缓存的副本。由于需要处理可能的多个并行调用之间的竞争条件,这比看起来要复杂。
【讨论】:
XHR 选项卡中可见。因此,用户可能只是为了好玩而单击 php 文件并调用它。顺便说一句,这也是一个问题——如何防止它们被看到?