Authenticating and protecting Ajax requests with PHP
<?php | |
if (session_status() == PHP_SESSION_NONE) { | |
session_start();//Start session if none exists/already started | |
} | |
if (isset($_POST['ajax_call']) || isset($_GET['ajax_call'])) { | |
$headers = getallheaders(); | |
if (isset($headers['token'])) { | |
$header_token = $headers['token']; | |
if ($header_token != $_SESSION['token']) { | |
echo "ERROR: Tokens dont match"; | |
exit; | |
} | |
} else { | |
echo "ERROR: No token sent"; | |
exit; | |
} | |
if (isset($_POST['ajax_call'])) {//POST call | |
if (isset($_SERVER['HTTP_ORIGIN'])) { | |
$address = 'https://' . $_SERVER['SERVER_NAME']; | |
if (strpos($address, $_SERVER['HTTP_ORIGIN']) == 0) { | |
echo "POST SUCCESS! [token = session token], [HTTP origin = server host]"; | |
//Do the POST request | |
//........ | |
} | |
} else { | |
echo "POST ERROR: No Origin header"; | |
} | |
} elseif (isset($_GET['ajax_call'])) {//GET call | |
if (isset($_SERVER['HTTP_REFERER'])) { | |
if (parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) != $_SERVER['HTTP_HOST']) { | |
echo "ERROR: External GET request"; | |
exit; | |
} | |
echo "GET SUCCESS! [token = session token], [referer = host (" . parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) . " = {$_SERVER['HTTP_HOST']})]"; | |
//Return data from GET request | |
//........ | |
} else { | |
echo "GET ERROR: No HTTP referer"; | |
exit; | |
} | |
} | |
} else { | |
echo "ERROR: Not a GET or POST request"; | |
exit; | |
} |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css"/> | |
<?php | |
if (session_status() == PHP_SESSION_NONE) { | |
session_start(); | |
} | |
if (isset($_GET['get_token']) && empty($_SESSION["token"])) { | |
$token = bin2hex(random_bytes(64)); | |
$_SESSION["token"] = $token; | |
} | |
if (isset($_GET['kill_token'])) { | |
unset($_SESSION["token"]); | |
session_destroy(); | |
} | |
?> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-12"> | |
<?php | |
if (isset($_SESSION["token"])) { | |
echo '<meta name="token" content="' . $_SESSION["token"] . '">'; | |
?> | |
<p><?php echo "Token is set:</p> <code>{$_SESSION["token"]}</code><br>"; ?> | |
<a class="btn btn-danger btn-sm" href="?kill_token" role="button">Kill token</a> | |
<?php | |
} else { | |
?> | |
<p>Token not set </p><code> </code><br> | |
<a class="btn btn-success btn-sm" href="?get_token" role="button">Get token</a> | |
<?php | |
} | |
?> | |
<a id="POSTcallBtn" class="btn btn-secondary btn-sm" href="#" role="button">Do ajax POST call</a> | |
<a id="GETcallBtn" class="btn btn-secondary btn-sm" href="#" role="button">Do ajax GET call</a> | |
<div id="resultsDiv" class="mt-3"><b><p id="resultText"></p></b></div> | |
</div> | |
</div> | |
</div> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> | |
<script type="application/javascript"> | |
function demoCallTemplate(request_type) { | |
const token = $('meta[name="token"]').attr('content'); | |
$("#resultText").empty(); | |
$.ajax({ | |
type: request_type, | |
url: "api.php", | |
headers: {"token": token}, | |
data: {"ajax_call": true}, | |
success: function (result) { | |
$("#resultText").text(result); | |
} | |
}); | |
} | |
$(document).on("click", "#POSTcallBtn", function () { | |
demoCallTemplate('POST'); | |
}); | |
$(document).on("click", "#GETcallBtn", function () { | |
demoCallTemplate('GET'); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment