有没有办法防止在浏览器中单独查看AJAX页面?

时间:2010-08-26 23:03:39

标签: php ajax security

例如,当我想用​​AJAX更新我的页面的一部分时,我通常会对getPost.php进行适当的调用,这将返回要插入到我的页面中的标记。有没有办法阻止用户直接访问此页面(例如:带有适当的GET或POST参数的example.com/getPost.php)并且只获取页面的一部分,因为这应该与AJAX一起使用作为整体的一部分,不是一个人?

我不认为可以在文件上设置权限,因为它是请求页面的客户端,但有一种方法可以通过传递一个额外的参数来完成此操作,该参数可以作为排序的校验位。

6 个答案:

答案 0 :(得分:8)

您可以查看请求标头并强制必须为AJAX请求设置标头(通常人们使用X-Requested-With来使用XMLHttpRequest之类的值。请注意,除非您在发出AJAX请求时自行设置(或使用自动执行此操作的Javascript库),否则不会设置此标头。但是,没有办法保证如果他们愿意,有人不会自己添加标题。

可以在X-Requested-With中找到$_SERVER['HTTP_X_REQUESTED_WITH']标头值。

答案 1 :(得分:3)

您可以检查$ _SERVER ['HTTP_X_REQUESTED_WITH']标头。如果它是Ajax请求,它应该等于值'XMLHttpRequest'。

编辑 - 就像Daniel Vandersluis所说,没有办法完全执行此操作。您可以欺骗用户代理,引荐来源 - 请求中包含的任何内容。

答案 2 :(得分:2)

您向服务器请求的内容,它将信息存储在$_SERVER变量

检查此变量存储的信息尝试此

print_r($_SERVER);

//you will see the difference in http and ajax request 

使用此变量检查为

if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
    strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
   //ajajx request
}
else {
   //not an ajajx request
}

答案 3 :(得分:1)

由于没有办法100%确定谁在提问,你可以自己限制问题。

这个的实现当然取决于页面。

例如,假设您在网址上运行curl命令,可以将传入变量限制为仅限某个域。

<?php
if (substr($_GET["url"], 0, 19) !== "http://example.com/")
{
    die();
}
// otherwise carry on
?>

答案 4 :(得分:1)

不应该这样吗?

if(preg_match("/getPost\.php/", $_SERVER['PHP_SELF'])){
     // Access to file directly, quit..
     die();
}

答案 5 :(得分:0)

我认为你可以(至少部分地)用加密技术来解决你的问题。

假设您有一个页面main.php,其中包含JS以调用另一个名为ajax.php的页面。访问网页main.php时,使用$browserKey$salt创建$_SESSION["tempHash"]。 (您还需要存储salt。)然后,给出向您的页面ajax.php发出请求的JavaScript的密钥,并检查密钥和salt是否提供与以前相同的哈希值。在main.php上,执行以下操作:

<?php
session_start();
// authorize user here
$salt = time();
$browserKey = mt_rand();
$hash = sha1("$browserKey$salt");
$_SESSION["tempSalt"] = $salt;
$_SESSION["tempHash"] = $hash;
// ... code ...
?>
<!doctypehtml>
<html>
<!-- html -->
<script>
// ... ajax call ...
var params = "param1=val1&param2=val2&...&browserKey=<?= $browserKey ?>";
request.send(params);
</script>
</html>
<?php session_write_close(); ?>

然后,在ajax.php上,只需执行

<?php
$validated = false;
if(sha1($_POST["browserKey"] . $_SESSION["tempSalt"]) === $_SESSION["tempHash"]) {
    $validated = true;
}
// and unset the salt and hash
$_SESSION["tempSalt"] = $_SESSION["tempHash"] = null;
if(!$validated) {
    // taken from another SO answer: 
    // http://stackoverflow.com/a/437294/2407870
    header('HTTP/1.0 404 Not Found');
    echo "<h1>404 Not Found</h1>";
    echo "The page that you have requested could not be found.";
    exit();
}
// else, continue normal processing here
?>

我不是这个领域的专家,所以请用我的建议加上一些 salt 。 (嘿,加密笑话。)

此方法的一个潜在漏洞是此人可能会加载页面main.php,然后等待五个小时并调用页面ajax.php。它仍然只允许他们访问一次。你可以做其他事情来防止这种情况发生。例如,检查盐(使用time()获得)以确认没有太多时间过去。或者甚至向服务器发送定期心跳,生成新的哈希,盐和密钥,将新密钥返回给浏览器。