Ultimately you cant secure any public resource from screen scrapping...Read More, but if your looking to just add a basic layer of protection from someone just scripting something that directly access's your sites API, then you can set a single use CSRF token on to the AJAX request, also a wise step is to not use GET and use POST instead.
Here's a quick example, upon the client loading the page you set some tokens into the session, and add the tokens to the AJAX:
<?php
session_start();
$_SESSION['csrf_ajax_key'] = sha1(uniqid());
$_SESSION['csrf_ajax_val'] = sha1(uniqid());
?>
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<body>
<span id="result">Ajax response goes here...</span>
<script>
var request = $.ajax({
type: "POST",
url: "yourAPI.php",
data: {"url":"facebook.com", "<?php echo $_SESSION['csrf_ajax_key'];?>":"<?php echo $_SESSION['csrf_ajax_val'];?>"}
});
request.done(function(response) {
$("#result").html(response);
});
request.fail(function(jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
});
</script>
</body>
</html>
Then on your API do some simple checks to check that the keys are set, its a xmlhttprequest(AJAX) and is a POST request. Then unset the session keys to stop multiple requests or you could return new keys for subsequent requests (if your polling).
<?php
session_start();
if(
//Check required variables are set
isset($_SESSION['csrf_ajax_key']) &&
isset($_SESSION['csrf_ajax_val']) &&
isset($_POST[$_SESSION['csrf_ajax_key']]) &&
isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
//Check is AJAX
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest' &&
//Check is POST
$_SERVER['REQUEST_METHOD'] === 'POST' &&
//Check POST'ed keys match the session keys
$_SESSION['csrf_ajax_val'] == $_POST[$_SESSION['csrf_ajax_key']]
){
//good - example
if(isset($_POST['url']) && $_POST['url']=='facebook.com'){
echo 'This is the response for facebook.com';
}
}
//Unset to stop multiple attempts
unset($_SESSION['csrf_ajax_val'], $_SESSION['csrf_ajax_key']);
?>
Though its not 100% but will stop most.