The php
code below allows only the URL http://example1.com
to have access to the application. How can I allow access only to the four URLs below in PHP?
http://example1.com
http://example2.com
http://example3.com
http://example4.com
<?php
error_reporting(0);
header('Access-Control-Allow-Origin: http://example1.com');
header('Access-Control-Allow-Methods: POST');
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
$allowedOrigin = 'http://example1.com'; // Your expected origin
if ($_SERVER['HTTP_ORIGIN'] !== $allowedOrigin) {
//echo "Access Denied.";
$return_arr = array("msg"=>"Access Denied");
echo json_encode($return_arr);
exit();
}
$validReferer = 'http://example1.com/'; // Change to your actual domain! Include trailing slash if the AJAX call comes from a subfolder
if (strpos($_SERVER['HTTP_REFERER'], $validReferer) !== 0) {
// echo "Access Denied (Invalid Referer).";
$return_arr = array("msg"=>"Access Denied");
echo json_encode($return_arr);
exit();
}
// begin insert records into database
?>
Before outputting your Access-Control-Allow-Origin
header, check to see if the Origin
request header is an allowed origin. This is most easily done by having an array of allowed origins and using in_array
. You could also do more complex approaches (e.g. using a regular expression) but be careful not to be more permissive that you need to be.
If it is, then use that value in the response.
If the request is a (preflight) OPTIONS request, then don't do any further processing. Just respond that it is OK to send the actual request.
A basic approach to that would be:
<?php
$method = $_SERVER['REQUEST_METHOD'];
$origin = $_SERVER['HTTP_ORIGIN'];
$allowed_origins = ['http://example.com', 'http://example.net'];
if (!in_array($origin, $allowed_origins)) {
# Stop here if the origin isn't in the allowed list
# You might want to allow for the case where there is NO origin header
# indicating that it is a *same origin* request. (Or a non-browser request).
exit();
}
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Methods: POST');
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
if ($method === "OPTIONS") {
# Exit here so that any code that might try to read the request body
# and insert into the database won't fail due to the body not being
# present on the OPTIONS request.
exit();
}
# Further processing here
However, there are plenty of prebuilt solutions out that which are probably more robust that this so you should consider one of them instead. Particularly if you are using any kind of framework.
Ignore the Referer header. It isn't useful.
Don't go straight to inserting data into a database. CORS only defends against third party websites getting their users to access your site (with any cookies and so on that their users might already have for your site). It doesn't prevent people from making HTTP requests to your web service directly. You are allowing the Authorization header, so do your AuthN/AuthZ before inserting anything into your database.