代码之家  ›  专栏  ›  技术社区  ›  alexcoco akvallejos

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

  •  8
  • alexcoco akvallejos  · 技术社区  · 14 年前

    例如,当我想用AJAX更新页面的一部分时,我通常会调用获取帖子.php它将返回要插入到我的页面中的标记。有没有办法阻止用户直接访问此页面(例如:example.com/getPost.php)并且只获取页面的一部分,因为这应该作为整个AJAX的一部分而不是单独使用?

    我不认为可以在文件上设置权限,因为它是请求页面的客户机,但是有没有方法通过传递一个额外的参数来实现这一点,这个参数可以作为排序的检查数字。

    6 回复  |  直到 14 年前
        1
  •  8
  •   Daniel Vandersluis    14 年前

    您可以查看请求头并强制要求必须为AJAX请求设置头(通常人们使用 X-Requested-With 具有如下值 XMLHttpRequest

    这个 $_SERVER['HTTP_X_REQUESTED_WITH'] .

        2
  •  3
  •   efritz    14 年前

    编辑-就像丹尼尔·范德斯路易斯说的,没有办法完全执行这一点。你可以欺骗用户代理,推荐人-任何随请求而来的东西。

        3
  •  2
  •   Peter Ajtai    14 年前

    无论您向服务器请求什么,它都会将信息存储在 $_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
    }
    
        4
  •  1
  •   Peter Ajtai    14 年前

    既然没有办法百分之百确定谁在问这个问题,你可以限制问题本身。

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

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

    这不管用吗?

    if(preg_match("/getPost\.php/", $_SERVER['PHP_SELF'])){
         // Access to file directly, quit..
         die();
    }
    
        6
  •  0
  •   Chris Middleton    10 年前

    我认为你可以(至少部分地)用密码学解决你的问题。

    假设你有一页 main.php 其中包括JS调用另一个名为 ajax.php 主要.php $browserKey 和一个 $salt $_SESSION["tempHash"] . (您还需要存储salt。)然后,为向页面发出请求的JavaScript提供键 ajax.php文件 主要.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(); ?>
    

    然后,继续 ,简单地做

    <?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
    ?>
    

    我不是这个领域的专家,所以请接受我的建议 . (哈哈,开个玩笑。)

    这种方法的一个潜在漏洞是用户可能会加载页面 主要.php 然后等五个小时再打电话给佩奇 ajax.php文件 . 它仍然只允许他们访问它一次。你可以采取其他措施来防止这种情况。例如,检查盐(是用 time()