Partager des ressources entre origines de manière sécurisée
Le règlement d'origine identique du navigateur bloque la lecture d'une ressource à partir d'une autre origine. Ce mécanisme empêche les sites malveillants de lire les données d'autres sites, mais il empêche également les utilisations légitimes.
Les applications Web modernes souhaitent souvent obtenir des ressources à partir d'une autre origine, par exemple en récupérant des données JSON à partir d'un autre domaine ou en chargeant des images d'un autre site dans un élément <canvas>
. Il peut s'agir de ressources publiques qui doivent être accessibles à tous, mais la règle d'origine commune bloque leur utilisation. Les développeurs ont traditionnellement utilisé des solutions de contournement telles que JSONP.
Le partage des ressources entre origines multiples (CORS) résout ce problème de manière standardisée. L'activation de CORS permet au serveur d'indiquer au navigateur qu'il peut utiliser une origine supplémentaire.
Comment fonctionne une requête de ressources sur le Web ?
Un navigateur et un serveur peuvent échanger des données sur le réseau à l'aide du protocole HTTP (Hypertext Transfer Protocol). HTTP définit les règles de communication entre le demandeur et le répondeur, y compris les informations nécessaires pour obtenir une ressource.
L'en-tête HTTP négocie l'échange de messages entre le client et le serveur, et permet de déterminer l'accès. La requête du navigateur et le message de réponse du serveur sont tous deux divisés en en-tête et corps.
En-tête
Informations sur le message, telles que le type ou l'encodage du message. Un en-tête peut inclure une variété d'informations exprimée sous forme de paires clé/valeur. L'en-tête de requête et l'en-tête de réponse contiennent des informations différentes.
Exemple d'en-tête de requête
Accept: text/html
Cookie: Version=1
Cet en-tête équivaut à dire "Je souhaite recevoir du code HTML en réponse. Voici un cookie que j'ai. »
Exemple d'en-tête de réponse
Content-Encoding: gzip
Cache-Control: no-store
Cet en-tête équivaut à dire "Les données de cette réponse sont encodées avec gzip. Ne mettez pas cela en cache."
Corps
Le message lui-même. Il peut s'agir de texte brut, d'un binaire d'image, de JSON, de HTML ou de nombreux autres formats.
Comment fonctionne le CORS ?
Les règles de même origine indiquent au navigateur de bloquer les requêtes d'origines multiples. Lorsque vous avez besoin d'une ressource publique provenant d'une autre origine, le serveur fournissant la ressource indique au navigateur que l'origine qui envoie la requête peut accéder à sa ressource. Le navigateur s'en souvient et autorise le partage de ressources entre origines pour cette ressource.
Étape 1: requête du client (navigateur)
Lorsque le navigateur envoie une requête multi-origine, il ajoute un en-tête Origin
avec l'origine actuelle (schéma, hôte et port).
Étape 2 : Réponse du serveur
Lorsqu'un serveur voit cet en-tête et souhaite autoriser l'accès, il ajoute un en-tête Access-Control-Allow-Origin
à la réponse spécifiant l'origine de la requête (ou *
pour autoriser n'importe quelle origine).
Étape 3 : Le navigateur reçoit la réponse
Lorsque le navigateur voit cette réponse avec un en-tête Access-Control-Allow-Origin
approprié, il partage les données de réponse avec le site client.
Partager des identifiants avec CORS
Pour des raisons de confidentialité, le CORS est généralement utilisé pour les requêtes anonymes, dans lesquelles l'auteur de la requête n'est pas identifié. Si vous souhaitez envoyer des cookies lorsque vous utilisez CORS, qui peut identifier l'expéditeur, vous devez ajouter des en-têtes supplémentaires à la requête et à la réponse.
Requête
Ajoutez credentials: 'include'
aux options de récupération, comme dans l'exemple suivant.
Cela inclut le cookie associé à la requête comme suit:
fetch('https://example.com', {
mode: 'cors',
credentials: 'include'
})
Réponse
Access-Control-Allow-Origin
doit être défini sur une origine spécifique (aucun caractère générique via *
) et Access-Control-Allow-Credentials
doit être défini sur true
.
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Requêtes préliminaires pour les appels HTTP complexes
Lorsqu'une application Web envoie une requête HTTP complexe, le navigateur ajoute une requête préliminaire au début de la chaîne de requêtes.
La spécification CORS définit une requête complexe comme suit :
- Requête qui utilise des méthodes autres que GET, POST ou HEAD.
- Requête incluant des en-têtes autres que
Accept
,Accept-Language
ouContent-Language
. - Requête dont l'en-tête
Content-Type
est différent deapplication/x-www-form-urlencoded
,multipart/form-data
outext/plain
.
Les navigateurs créent automatiquement toutes les requêtes de prévol nécessaires et les envoient avant le message de requête réel. La requête de prévol est une requête OPTIONS
, comme dans l'exemple suivant :
OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE
Côté serveur, l'application qui reçoit la requête répond à la requête de prévol avec des informations sur les méthodes que l'application accepte depuis cette origine :
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS
La réponse du serveur peut également inclure un en-tête Access-Control-Max-Age
pour spécifier la durée (en secondes) pendant laquelle les résultats de prévol doivent être mis en cache. Cela permet au client d'envoyer plusieurs requêtes complexes sans avoir à répéter la requête préliminaire.