I am trying to allow access to every subdomain on my site in order to allow cross subdomain AJAX calls. Is there a way to specify all subdomains of a site like *.example.com
or alternatively, why does the following not work when I have more than one domain listed:
header('Access-Control-Allow-Origin: http://api.example.com http://www.example.com');
I have read through the following question which appears to be similar, if not the same as this one, other than the fact that I want access to subdomains and this one refers to general domains.
Access-Control-Allow-Origin Multiple Origin Domains?
If the above question is the solution to this problem, then how am I able to retrieve the origin from the header. It appears that $_SERVER['HTTP_ORIGIN'] is very unreliable and not even cross browser. I need to be able to see the origin in any browser that may show an error when trying to send an AJAX call using javascript.
The solution to this issue is to use the $_SERVER['HTTP_ORIGIN']
variable to determine whether the request has come from an allowed domain, and then conditionally set the Access-Control-Allow-Origin
like so:
$allowed_domains = [/* Array of allowed domains*/];
if (in_array($_SERVER['HTTP_ORIGIN'], $allowed_domains)) {
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
}
Here's how I did it.
The Origin
header is specified by the browser and will contain the domain that requested the script on the other domain:
Origin: http://www.websiteA.com
Therefore you can "whitelist" multiple domains in your server-side script:
$allowedOrigins = [
"http://www.websiteA.com",
"https://www.websiteB.com"
// ... etc
];
What you can then do is check if the $_SERVER["HTTP_ORIGIN"]
global contains a domain within that whitelist:
if (in_array($_SERVER["HTTP_ORIGIN"], $allowedOrigins)) {
And set the Access-Control-Allow-Origin
response header to whatever Origin
header value was:
header("Access-Control-Allow-Origin: " . $_SERVER["HTTP_ORIGIN"]);
Full script:
$allowedOrigins = [
"http://www.websiteA.com",
"https://www.websiteB.com"
// ... etc
];
if (in_array($_SERVER["HTTP_ORIGIN"], $allowedOrigins)) {
header("Access-Control-Allow-Origin: " . $_SERVER["HTTP_ORIGIN"]);
}
While the answer works, it does defeat the purpose of the whole thing, since it allows requests from any host.
I use something like:
if(isset($_SERVER['HTTP_ORIGIN'])) {
$origin = $_SERVER['HTTP_ORIGIN'];
if($origin == 'https://sub1.my-website.com' OR $origin == 'https://sub2.my-website.com') {
header("Access-Control-Allow-Origin: $origin");
}
}
I tried using this approach to achieve constraint on a specific domain basis:
$allowed_origin = '';
$parts = explode('.', parse_url($_SERVER['HTTP_HOST'])['host']);
if(end($parts).".".prev($parts) === "com.domain") {
$allowed_origin = $_SERVER['HTTP_ORIGIN'];
header('Acesss-Control-Allow-Origin: '. $allowed_origin);
}
I hope it works.