Есть ли способ предотвратить просмотр страниц AJAX в браузере в одиночку? - PullRequest
8 голосов
/ 27 августа 2010

Например, когда я хочу обновить часть моей страницы с помощью AJAX, я обычно делаю соответствующий вызов getPost.php, который возвращает разметку, которая будет вставлена ​​на мою страницу.Есть ли способ предотвратить прямой доступ пользователя к этой странице (например, example.com/getPost.php с соответствующими аргументами GET или POST) и получить только часть страницы, поскольку это следует использовать с AJAX как часть целого, не один?

Я не думаю, что разрешения могут быть установлены для файла, поскольку клиент запрашивает страницу, но есть ли способ сделать это, передав дополнительный аргумент, который может служить контрольной цифройсортирует.

Ответы [ 6 ]

8 голосов
/ 27 августа 2010

Вы можете взглянуть на заголовки запроса и убедиться, что для запросов AJAX должен быть установлен заголовок (часто люди используют X-Requested-With со значением, например XMLHttpRequest). Имейте в виду, что этот заголовок не будет установлен, если вы не установите его самостоятельно, когда делаете запрос AJAX (или не используете библиотеку Javascript, которая делает это автоматически). Однако невозможно гарантировать, что кто-то сам не добавит этот заголовок, если захочет.

Значение заголовка X-Requested-With можно найти в $_SERVER['HTTP_X_REQUESTED_WITH'].

3 голосов
/ 27 августа 2010

Вы можете проверить заголовок $ _SERVER ['HTTP_X_REQUESTED_WITH'].Оно должно быть равно значению XMLHttpRequest, если это Ajax-запрос.

Редактировать - как сказал Дэниел Вандерслёйс, нет способа полностью обеспечить это.Вы можете подделать пользовательский агент, реферер - все, что приходит с запросом.

2 голосов
/ 27 августа 2010

что бы вы ни запрашивали на сервере, оно хранит информацию в $_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
}
1 голос
/ 27 августа 2010

разве это не должно работать?

if(preg_match("/getPost\.php/", $_SERVER['PHP_SELF'])){
     // Access to file directly, quit..
     die();
}
1 голос
/ 27 августа 2010

Поскольку невозможно быть на 100% уверенным, кто задает вопрос, вы можете ограничить сам вопрос.

Реализация этого будет зависеть от страницы, конечно.

Например, допустим, вы запускаете команду curl для URL, вы можете ограничить входящую переменную только определенным доменом.

<?php
if (substr($_GET["url"], 0, 19) !== "http://example.com/")
{
    die();
}
// otherwise carry on
?>
0 голосов
/ 12 сентября 2014

Я думаю, что вы можете (хотя бы частично) решить вашу проблему с помощью криптографии.

Скажем, у вас есть страница main.php, которая включает JS для вызова другой страницы с именем ajax.php. При доступе к странице main.php используйте $browserKey и $salt, чтобы создать $_SESSION["tempHash"]. (Вам также нужно хранить соль.) Затем дайте ключ к JavaScript, выполняющему запрос на вашу страницу ajax.php, и убедитесь, что ключ и соль дают тот же хеш, что и раньше. На 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
?>

Я не эксперт в этой области, поэтому примите мой совет с зерном соли . (Хех, криптографическая шутка.)

Одна потенциальная уязвимость при таком подходе заключается в том, что человек может загрузить страницу main.php, а затем подождать пять часов и вызвать страницу ajax.php. Это все еще только позволит им получить доступ к этому один раз все же. И вы можете сделать другие вещи, чтобы предотвратить это. Например, проверьте соль (которая была получена с time()), чтобы убедиться, что прошло не слишком много времени. Или даже периодически отправлять тактовые импульсы на сервер, который генерирует новый хэш, соль и ключ, возвращая новый ключ в браузер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...