Je voudrais vérifier côté serveur si une demande à ma page php est une demande ajax ou non.
J'ai vu deux façons de faire cela:
Première façon: envoyer un paramètre GET
dans la requête qui indique à la page qu'il s'agit d'une requête AJAX (= mypage.php?ajax
)
mypage.php:
if(isset($_GET['ajax'])) {
//this is an ajax request, process data here.
}
Deuxième manière: définir un en-tête sur xmlHttpRequest
:
js côté client:
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
}
Le fait est que ces deux manières de le faire peuvent facilement être piratées, il n'est donc pas sûr de vérifier si je reçois une demande AJAX comme celle-ci.
Comment puis-je vérifier si je reçois une demande AJAX?
Il n'y a pas de moyen sûr de savoir qu'une demande a été faite via Ajax. Vous ne pouvez jamais faire confiance aux données provenant du client. Vous pouvez utiliser plusieurs méthodes différentes, mais elles peuvent être facilement surmontées par l'usurpation d'identité.
Voici le tutorial pour atteindre le résultat.
Exemple:
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
{
exit;
}
continue;
Ceci vérifie si le paramètre
HTTP_X_REQUESTED_WITH
N'est pas vide et s'il est égal àxmlhttprequest
, il se terminera alors par le script.
Définissez une variable de session pour chaque page de votre site (pages réelles non incluses ou rpcs) contenant le nom de la page en cours, puis transmettez à votre appel Ajax un nonce salé avec le $_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>
Ensuite, dans le RPC que vous appelez testez le nonce que vous avez passé, s'il est bon, alors il y a de fortes chances que votre RPC soit légitimement appelé:
<?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 comme je l’ai défini, le nonce n’est valable que pendant une heure et change. Par conséquent, s’ils n’ont pas rafraîchi la page en effectuant l’appel ajax au cours de la dernière heure ou 2, la requête ajax échouera.
Cette fonction utilise dans le cadre yii) pour la vérification des appels ajax.
public function isAjax() {
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
}
$headers = Apache_request_headers();
$is_ajax = (isset($headers['X-Requested-With']) && $headers['X-Requested-With'] == 'XMLHttpRequest');
De PHP 7 avec l'opérateur de fusion nul, il sera plus court:
$is_ajax = 'XMLHttpRequest' == ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '' );
Essayez ci-dessous l'extrait de code
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
{
/* This is one ajax call */
}