Ciao a tutti,
scrivo in questa sezione perchè l'argomento non centra una mazza con joomla, ma può magari diventare utile per qualcuno.
Ho implementato in parallelo al sito in joomla delle pagine AMP: per bloccare alcuni elementi delle pagine previo consenso del visitatore (come cookies analitici) ho utilizzato il recente "amp-consent" (
https://www.ampproject.org/docs/reference/components/amp-consent ).
"amp-consent" necessita di un endpoint per funzionare a dovere, per verificare lo stato del consenso dato dal visitatore.
Tuttora, e quando ho implementato le pagine AMP, non avevo trovato esempi concreti a riguardo, o comunque non chiarissimi (almeno per me) e ho cercato di seguire le indicazioni date su ampproject.org -
https://www.ampproject.org/docs/fundamentals/amp-cors-requestsIn particolare, seguendo la documentazione, si dice:
If `Origin` header is set:
1. If the origin was not `*.ampproject.org`, `*.amp.cloudflare.com` or the publisher's (aka your) origin, stop and return an error response.
2. Check the `__amp_source_origin` query parameter. If it's not the publisher's origin stop and return an error response.
3. If both checks pass, proceed to process the request.
Otherwise, if `Origin` header is NOT set:
1. Check if the request has `AMP-Same-Origin: true` header. If not, stop and return an error response.
* This custom request header is sent by AMP runtime when making an XHR request on sameorigin (document served from non-cache URL).
2. Otherwise proceed to process the request.
It's very important that these all are done first before processing the request, this provides protection against CSRF attacks and avoids processing untrusted sources requests.
Si tratta quindi di effettuare una richiesta CORS di tipo POST a un endpoint, che ho scritto in php.
Premettendo che il dominio è indicato come mio-dominio.com, che ho un certificato https attivo e che ho i redirezionamenti da non-www a www e da http a https --> qui di seguito il codice dell'endpoint che ho scritto:
<?php
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
if (isset($_SERVER['HTTP_ORIGIN'])) {
$http_origin = $_SERVER['HTTP_ORIGIN'];
$amp_origin = $_REQUEST['__amp_source_origin'];
if (($http_origin == "https://www-mio--dominio-com.cdn.ampproject.org" || $http_origin == "https://mio--dominio-com.cdn.ampproject.org" || $http_origin == "https://cdn.ampproject.org" || $http_origin == "https://www-mio--dominio-com.amp.cloudflare.com" || $http_origin == "https://mio--dominio-com.amp.cloudflare.com" || $http_origin == "https://www.mio-dominio.com" || $http_origin == "https://mio-dominio.com") && ($amp_origin == "https://www.mio-dominio.com" || $amp_origin == "https://mio-dominio.com")) {
header("access-control-allow-credentials:true");
header("access-control-allow-headers:Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token");
header("access-control-allow-methods:POST");
header("access-control-allow-origin:".$_SERVER['HTTP_ORIGIN']);
header("access-control-expose-headers:AMP-Access-Control-Allow-Source-Origin");
header("amp-access-control-allow-source-origin:".$_REQUEST['__amp_source_origin']);
header("Content-Type: application/json");
$output = new \stdClass();
$output->promptIfUnknown = true;
echo json_encode($output);
}
else {
echo("something went wrong");
}
}
else {
$ampsameoriginvalue = "";
foreach (getallheaders() as $name => $value) {
if (strtoupper($name) == "AMP-SAME-ORIGIN") {
$ampsameoriginvalue = $value;
}
}
if ($ampsameoriginvalue == "true") {
$amp_origin = $_REQUEST['__amp_source_origin'];
if ($amp_origin == "https://www.mio-dominio.com" || $amp_origin == "https://mio-dominio.com") {
header("access-control-allow-credentials:true");
header("access-control-allow-headers:Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token");
header("access-control-allow-methods:POST");
header("access-control-allow-origin:https://www.mio-dominio.com");
header("access-control-expose-headers:AMP-Access-Control-Allow-Source-Origin");
header("amp-access-control-allow-source-origin:".$_REQUEST['__amp_source_origin']);
header("Content-Type: application/json");
$output = new \stdClass();
$output->promptIfUnknown = true;
echo json_encode($output);
}
else {
echo("something went wrong");
}
}
else {
echo("something went wrong");
}
}
}
else {
echo "post only";
}
?>
Quello che fa è:
1- verifica che la richiesta sia POST, altrimenti dai un messaggio di errore
2- verifica se l'header Origin è presente
3- se l'header Origin è presente: se il valore dell'header Origin è in whitelist e se amp origin è in whitelist, imposta gli header di risposta e procedi alla richiesta CORS, altrimenti dai un messaggio di errore
4- se l'header Origin non è presente verifica se negli header di richiesta esiste Amp-Same-Origin: true
5- se Amp-Same-Origin: true è presente imposta gli header e procedi alla richiesta CORS, altrimenti dai un messaggio di errore
6- se l'header Amp-Same-Origin: true non esiste dai un messaggio di errore
Ora, mi sembra che funzioni tutto correttamente, sia nella cache AMP, sia aprendo le pagine AMP direttamente su mio-dominio.com, ma visto che è la prima volta che mi approccio a CORS, magari mi è sfuggito qualcosa, magari a livello di sicurezza.
Anche perchè fino ad oggi, tutte le volte che ho aperto questo file l'ho modificato....
Magari se qualcuno ha voglia scorrendo il codice può capire se ho seguito correttamente il flusso delle istruzioni, o se ho fatto qualche cazzata...
EDIT: ops, mi sono accorto che
https://www.ampproject.org/docs/fundamentals/amp-cors-requests è stato aggiornato e ora c'è un esempio in javascript.