Condivisione delle risorse tra origini (CORS)

Condividi le risorse multiorigine in modo sicuro

Mariko Kosaka

Il criterio della stessa origine del browser blocca la lettura di una risorsa da un'origine diversa. Questo meccanismo impedisce a siti dannosi di leggere i dati di altri siti, ma impedisce anche gli utilizzi legittimi.

Le app web moderne spesso desiderano ottenere risorse da un'origine diversa, ad esempio recuperare dati JSON da un dominio diverso o caricare immagini da un altro sito in un elemento <canvas>. Queste possono essere risorse pubbliche che dovrebbero essere disponibili per la lettura a chiunque, ma il criterio della stessa origine ne blocca l'utilizzo. In passato gli sviluppatori hanno usato soluzioni alternative come JSONP.

La condivisione delle risorse tra origini (CORS) risolve questo problema in modo standardizzato. L'attivazione di CORS consente al server di indicare al browser che può utilizzare un'origine aggiuntiva.

Come funziona una richiesta di risorse sul web?

richiesta e risposta
Richiesta del client e risposta del server illustrate.

Un browser e un server possono scambiare dati sulla rete utilizzando l'Hypertext Transfer Protocol (HTTP). HTTP definisce le regole di comunicazione tra il richiedente e l'utente che risponde, incluse le informazioni necessarie per ottenere una risorsa.

L'intestazione HTTP negozia lo scambio del messaggio tra il client e il server ed è utilizzata per determinare l'accesso. Sia la richiesta del browser sia il messaggio di risposta del server sono suddivisi in intestazione e corpo.

Informazioni sul messaggio, come il tipo o la codifica. Un'intestazione può includere una serie di informazioni espresse come coppie chiave-valore. L'intestazione della richiesta e della risposta contengono informazioni diverse.

Intestazione della richiesta di esempio

Accept: text/html
Cookie: Version=1

Questa intestazione equivale a dire "Voglio ricevere HTML nella risposta. Ecco un biscotto che ho".

Intestazione risposta di esempio

Content-Encoding: gzip
Cache-Control: no-store

Questa intestazione equivale a dire "I dati in questa risposta sono codificati con gzip. Non memorizzare nella cache."

Body

Il messaggio stesso. Può trattarsi di testo normale, file binario dell'immagine, JSON, HTML o molti altri formati.

Come funziona CORS?

Il criterio della stessa origine indica al browser di bloccare le richieste multiorigine. Quando hai bisogno di una risorsa pubblica di un'origine diversa, il server che fornisce le risorse comunica al browser che l'origine che invia la richiesta può accedere alla sua risorsa. Il browser lo memorizza e consente la condivisione delle risorse tra origini per quella risorsa.

Passaggio 1: richiesta client (browser)

Quando il browser effettua una richiesta multiorigine, aggiunge un'intestazione Origin con l'origine corrente (schema, host e porta).

Passaggio 2: risposta del server

Quando un server vede questa intestazione e vuole consentire l'accesso, aggiunge un'intestazione Access-Control-Allow-Origin alla risposta che specifica l'origine della richiesta (oppure * per consentire qualsiasi origine).

Passaggio 3: il browser riceve risposta

Quando il browser vede questa risposta con un'intestazione Access-Control-Allow-Origin appropriata, condivide i dati della risposta con il sito del client.

Condividi le credenziali con CORS

Per motivi di privacy, CORS viene normalmente utilizzato per le richieste anonime, in cui il richiedente non è identificato. Se vuoi inviare i cookie quando utilizzi CORS, che può identificare il mittente, devi aggiungere altre intestazioni alla richiesta e alla risposta.

Richiesta

Aggiungi credentials: 'include' alle opzioni di recupero, come nell'esempio seguente. Questo include il cookie con la richiesta come segue:

fetch('https://example.com', {
  mode: 'cors',
  credentials: 'include'
})

Risposta

Access-Control-Allow-Origin deve essere impostato su un'origine specifica (nessun carattere jolly utilizzando *) e Access-Control-Allow-Credentials deve essere impostato su true.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

Richieste preflight per chiamate HTTP complesse

Quando un'app web effettua una richiesta HTTP complessa, il browser aggiunge una richiesta preflight all'inizio della catena di richieste.

La specifica CORS definisce una richiesta complessa come segue:

  • Una richiesta che utilizza metodi diversi da GET, POST o HEAD.
  • Una richiesta che include intestazioni diverse da Accept, Accept-Language o Content-Language.
  • Una richiesta con un'intestazione Content-Type diversa da application/x-www-form-urlencoded, multipart/form-data o text/plain.

I browser creano automaticamente tutte le richieste preflight necessarie e le inviano prima del messaggio di richiesta effettivo. La richiesta preflight è una richiesta OPTIONS come nell'esempio seguente:

OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE

Sul lato server, l'app che riceve la richiesta risponde alla richiesta preflight con informazioni sui metodi accettati dall'applicazione da questa origine:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS

La risposta del server può includere anche un'intestazione Access-Control-Max-Age per specificare la durata in secondi di memorizzazione nella cache dei risultati preflight. Ciò consente al client di inviare più richieste complesse senza dover ripetere la richiesta preflight.