我需要允许只通过Ajax和Cron调用php脚本,而不是通过它在浏览器中的地址调用。
在F12中,所有的php脚本都是可见的,任何用户都可以调用php脚本,如website.com/file.php
答案 0 :(得分:0)
你不能。脚本不知道它们是如何被调用的;他们所知道的是,Web服务器已经调用了它们。
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调用,但只有第一个会执行任何实际工作 - 另一个将等待锁定的文件,然后读取缓存的副本。由于需要在可能的几个并行调用之间处理竞争条件,这比看起来更棘手。