Я хотел бы проверить серверную сторону, если запрос на мою php-страницу является запросом ajax или нет.
Я видел два способа сделать это:
Первый способ: отправка параметра GET
в запросе, который сообщает странице, что это запрос AJAX (= mypage.php?ajax
)
mypage.php:
if(isset($_GET['ajax'])) { //this is an ajax request, process data here. }
Второй способ: установить заголовок для xmlHttpRequest
:
клиентская сторона js:
xmlHttpRequestObject.open(“GET”,url,true); xmlHttpRequestObject.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
mypage.php:
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' ) { //request is ajax }
Дело в том, что эти два способа сделать это можно легко взломать, так что небезопасно проверять, получил ли я такой запрос AJAX.
Как я могу проверить, получаю ли я запрос AJAX?
Нет никакого уверенного способа узнать, что запрос был сделан через Ajax. Вы не можете доверять данным, поступающим от клиента. Вы можете использовать несколько различных методов, но их легко преодолеть путем подмены.
Вот учебник по достижению результата.
Пример:
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { exit; } continue;
Это проверка, что параметр
HTTP_X_REQUESTED_WITH
не пуст, и если он равенxmlhttprequest
, он соответствует этому, и он выйдет из сценария.
Задайте переменную сеанса для каждой страницы вашего сайта (фактические страницы не включают или rpcs), которая содержит текущее имя страницы, а затем в вашем вызове ajax переходите на ноль со значением $ _SERVER ['SCRIPT_NAME']:
<?php function create_nonce($optional_salt='') { return hash_hmac('sha256', session_id().$optional_salt, date("YmdG").'someSalt'.$_SERVER['REMOTE_ADDR']); } $_SESSION['current_page'] = $_SERVER['SCRIPT_NAME']; ?> <form> <input name="formNonce" id="formNonce" type="hidden" value="<?=create_nonce($_SERVER['SCRIPT_NAME']);?>"> <label class="form-group"> Login<br /> <input name="userName" id="userName" type="text" /> </label> <label class="form-group"> Password<br /> <input name="userPassword" id="userPassword" type="password" /> </label> <button type="button" class="btnLogin">Sign in</button> </form> <script type="text/javascript"> $("form.login button").on("click", function() { authorize($("#userName").val(),$("#userPassword").val(),$("#formNonce").val()); }); function authorize (authUser, authPassword, authNonce) { $.ajax({ type: "POST", url: "/inc/rpc.php", dataType: "json", data: "userID="+authUser+"&password="+authPassword+"&nonce="+authNonce }) .success(function( msg ) { //some successful stuff }); } </script>
Затем в rpc вы вызываете тест nonce, который вы передали, если это хорошо, то коэффициенты довольно велики, что ваш rpc был законно вызван:
<?php function check_nonce($nonce, $optional_salt='') { $lasthour = date("G")-1<0 ? date('Ymd').'23' : date("YmdG")-1; if (hash_hmac('sha256', session_id().$optional_salt, date("YmdG").'someSalt'.$_SERVER['REMOTE_ADDR']) == $nonce || hash_hmac('sha256', session_id().$optional_salt, $lasthour.'someSalt'.$_SERVER['REMOTE_ADDR']) == $nonce) { return true; } else { return false; } } $ret = array(); header('Content-Type: application/json'); if (check_nonce($_POST['nonce'], $_SESSION['current_page'])) { $ret['nonce_check'] = 'passed'; } else { $ret['nonce_check'] = 'failed'; } echo json_encode($ret); exit; ?>
edit: FYI, как я его устанавливал, nonce хорош только на час и меняется, поэтому, если они не обновили страницу, выполняющую вызов ajax за последний час или 2, запрос ajax не удастся.
$headers = apache_request_headers(); $is_ajax = (isset($headers['X-Requested-With']) && $headers['X-Requested-With'] == 'XMLHttpRequest');
Вы можете попробовать использовать переменную $_SESSION
чтобы убедиться, что запрос был сделан из браузера. В противном случае вы можете отправить запрос через базу данных или файл [на стороне сервера].