Skip to content

Instantly share code, notes, and snippets.

@cp6
Created February 7, 2021 02:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cp6/a6fd80fbb7ff7c89fa44246bd1885f3f to your computer and use it in GitHub Desktop.
Save cp6/a6fd80fbb7ff7c89fa44246bd1885f3f to your computer and use it in GitHub Desktop.
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