为什么阻止直接url访问也会破坏Web服务器上文件的Ajax调用


Why blocking direct url access also demolishes Ajax call from a file on the webserver?

我想阻止Url(外部)访问文件夹"/mi-PHP/"中的PHP文件。因此,我在/mi-php文件夹中创建了一个.htaccess文件,其中包含以下代码:

<Files *.php>
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Files>

当然,php文件被阻止直接访问url。然而,当我尝试在Web服务器上的一个文件中使用Ajax调用这个php(/mi-php/jobdata.php)文件时,如下所示:

$(document).ready( function () { $.getJSON("/mi-php/jobdata.php", function(data){ etc etc

它也被阻塞了。我认为通过同一网站根目录下的另一个文件进行调用被认为是"localhost"访问。我想我错了。但是,如何使php文件只能访问根目录下我自己的文件呢?

我看不出有任何防弹的方法可以解决这个问题。我唯一能想到的方法就是看看这个调用是否是Ajax调用。

if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
    die();
}

根据David Walsh的博客文章

您需要将上面的代码段添加到要阻止的每个文件的顶部。有两件事需要考虑。

  1. 任何人都可以修改他们调用的头并添加上面的头
  2. 有些服务器/ajax客户端不发送这个头(Apache和jQuery发送)

您可以在脚本中检查更多内容,但这将是一个开始。

我在评论中建议的方法如下:

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$ 
RewriteCond %{HTTP_REFERER} !^http://(www'.)?arvixe'.com/ [NC] 
RewriteRule ^mi-php(/|$) - [F,NC]

以上内容将出现在httpd服务器的文档根目录中。

请注意,客户端可以发送伪造的标头来绕过这些标头。此外,正如Magnus所建议的,这些值可能会从请求中删除,完全与用户的防火墙/ISP设置有关。不要100%依赖于此。


您可以尝试的另一种方法是,在AJAX调用之前,将以下值存储在会话变量中:

<?php $_SESSION['ajax'] = 'allowed';

现在,在将使用AJAX调用请求的文件中,在每个文件的开头进行以下检查:

<?php
    session_start();
    if( !isset($_SESSION['ajax']) and $_SESSION['ajax'] !== 'allowed' )
        die();
    else
        unset( $_SESSION['ajax'] );
?>