jamescridland
jamescridland

Reputation: 745

How to output the correct headers for amp-form in PHP?

The documentation around CORS headers for amp-forms could be easier, and I'm still a bit of a loss whether I've done everything right.

Right now, my form appears to work from my own website as well as from Google's AMP result. It doesn't work from my development website, though; and I'm also not sure whether it is really very secure. Here is the code I'm using so far, to a script that lives on https://podnews.net

This has been the result of a lot of trial and error, and I can't help thinking that the documentation could be much clearer around this issue.

header('Cache-Control: private, no-cache');
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Credentials: true');
header('access-control-expose-headers: AMP-Access-Control-Allow-Source-Origin');
header('AMP-Access-Control-Allow-Source-Origin: https://podnews.net');
header('Content-Type: application/json');

Particularly: $_SERVER['HTTP_ORIGIN'] can include AMP caches, as I understand it.

What are the correct valid values here? How can I add more than one value (given there are at least two AMP caches out there)? Why isn't it working on the development site, which is something like http://dev.podnews.net (the error it kicks up is the CORS one, not one about being in HTTP not HTTPS). How can I write this up so that all AMP developers have an easy reference?

Upvotes: 3

Views: 1625

Answers (1)

jamescridland
jamescridland

Reputation: 745

After a lot more fiddling, I think the answer is the rather unwieldy code here:

header('Cache-Control: private, no-cache');

$thisDomain="https://podnews.net"; // The main production domain
$devDomain="http://dev.podnews.net"; // The development domain

$googleAMPCacheSubdomain=str_replace(".","-",str_replace("-","--",$thisDomain));

//If you use an IDN, you've got more work to do in the above to work out your AMP cache subdomain
//https://github.com/ampproject/amphtml/blob/master/spec/amp-cors-requests.md has details

$validOrigins=array('https://'.$googleAMPCacheSubdomain.'.cdn.ampproject.org','https://cdn.ampproject.org','https://amp.cloudflare.com',$thisDomain,$devDomain);

if (!in_array($_SERVER['HTTP_ORIGIN'],$validOrigins)) {
    header('X-Debug: '.$_SERVER['HTTP_ORIGIN'].' is an unrecognised origin');
    header('HTTP/1.0 403 Forbidden');exit;

    //Stop doing anything if this is an unfamiliar origin
}

if ($_GET['__amp_source_origin']!=$thisDomain AND $_GET['__amp_source_origin']!=$devDomain) {
    header('X-Debug: '.$_GET['__amp_source_origin'].' is an unrecognised source origin');
    header('HTTP/1.0 403 Forbidden');exit;

    //Stop doing anything if this is an unfamiliar source origin
    //Note: if using Amazon Cloudfront, don't forget to allow query strings through
}

header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Expose-Headers: AMP-Access-Control-Allow-Source-Origin');
header('AMP-Access-Control-Allow-Source-Origin: '.urldecode($_GET['__amp_source_origin']));
header('Content-Type: application/json');
// You're in!

I do hope this is a nice copy/paste-able answer that others might find useful. It's a lot of hard work!

Upvotes: 6

Related Questions