Bonne journée, mes amis!
Je présente à votre attention la traduction de l'article "CS Visualized: CORS" de Lydia Hallie.
Chaque développeur a dû faire face à une erreur
Access to fetched has been blocked by CORS policy
. Il existe plusieurs façons de résoudre rapidement ce problÚme. Cependant, prenons notre temps et examinons de plus prÚs ce qu'est une politique CORS.
Nous avons souvent besoin d'afficher des donnĂ©es situĂ©es ailleurs. Avant de pouvoir faire cela, le navigateur doit envoyer une requĂȘte au serveur pour recevoir ces donnĂ©es.
Disons que nous voulons obtenir des informations sur un utilisateur sur notre site Ă
www.mywebsite.com
partir d'un serveur situé sur le site api.website.com
.
Excellent! Nous venons d'envoyer une requĂȘte au serveur et de recevoir des donnĂ©es JSON en rĂ©ponse.
Essayons maintenant d'envoyer une demande similaire Ă un autre domaine. Au lieu d'envoyer une demande avec,
www.mywebsite.com
envoyons-la avec www.anotherdomain.com
.
Qu'est-il arrivĂ©? Nous avons envoyĂ© exactement la mĂȘme demande, mais cette fois, le navigateur affiche une sorte d'erreur.
Nous voyons CORS en action. Pourquoi cette erreur s'est-elle produite et qu'est-ce que cela signifie?
Politique d'origine commune
Il existe quelque chose sur le Web appelĂ© Generic Origin Policy (ci-aprĂšs dĂ©nommĂ© POP). Par dĂ©faut, nous n'avons accĂšs qu'aux ressources qui ont la mĂȘme origine que l'origine de notre demande. Par exemple, nous pouvons charger une image situĂ©e dans
https://mywebsite.com/image1.png
.
Une source est différente lorsqu'elle se trouve dans un (sous) domaine, protocole ou port différent.
Cool, mais pourquoi avez-vous besoin de POP?
Disons que cela n'existe pas et que vous cliquez accidentellement sur un lien viral que votre tante a publié sur Facebook. Ce lien vous redirige vers un "site malveillant" doté d'une iframe intégrée qui charge le site de votre banque et s'y connecte avec succÚs à l'aide d'un cookie.
Les développeurs du "site maléfique" se sont assurés qu'il avait accÚs à l'iframe et pouvait interagir avec le contenu du DOM du site de votre banque pour transférer des fonds sur son compte en votre nom.
Ouais ... c'est un grave problÚme de sécurité. Nous ne voulons pas que quiconque ait accÚs à quoi que ce soit à notre insu.
Heureusement, EPP existe. Cette politique limite l'accĂšs aux ressources d'autres sources.
Dans ce cas, la source
www.evilwebsite.com
tente d'accéder à la ressource depuis la source www.bank.com
. EPP bloque cet accĂšs et empĂȘche les mauvais dĂ©veloppeurs de sites d'accĂ©der Ă vos donnĂ©es bancaires.
D'accord, mais ... comment ça marche?
CORS cÎté client
MĂȘme si EPP ne s'applique qu'aux scripts, les navigateurs "l'Ă©tendent" Ă toutes les requĂȘtes JavaScript: par dĂ©faut, nous n'avons accĂšs qu'aux ressources d'une seule source.
Hmm, mais ... nous avons souvent besoin d'obtenir des ressources d'une autre source. Peut-ĂȘtre que notre frontend doit accĂ©der Ă l'API du serveur pour charger les donnĂ©es. Pour rĂ©cupĂ©rer en toute sĂ©curitĂ© des ressources Ă partir d'autres sources, les navigateurs implĂ©mentent un mĂ©canisme appelĂ© CORS.
CORS est l'acronyme de Cross-Origin Resource Sharing. Bien que les navigateurs interdisent les ressources provenant d'autres sources, nous pouvons utiliser CORS pour modifier cette restriction tout en restant en sécurité.
Les agents utilisateurs (navigateurs) peuvent utiliser CORS pour rĂ©soudre les demandes d'origine croisĂ©e qui seraient autrement bloquĂ©es en fonction de certains en-tĂȘtes de rĂ©ponse HTTP.
Lorsqu'une requĂȘte est faite Ă une autre source, le client ajoute automatiquement un en-tĂȘte Ă la requĂȘte HTTP
Origin
. La valeur de cet en-tĂȘte est la source de la demande.
Pour que le navigateur autorise la rĂ©cupĂ©ration de ressources Ă partir d'une autre source, la rĂ©ponse du serveur doit Ă©galement contenir un en-tĂȘte spĂ©cifique.
CORS cÎté serveur
En tant que dĂ©veloppeurs backend, nous pouvons permettre Ă d'autres sources d'obtenir nos ressources en incluant des en-tĂȘtes spĂ©ciaux commençant par
Access-Control-*
. En fonction de la valeur de ces en-tĂȘtes, le navigateur autorise le partage de ressources.
Il y a plusieurs CORS- en -tĂȘtes, mais l' un d'entre eux est un must:
Access-Control-Allow-Origin
.
La signification de cet en-tĂȘte dĂ©termine les sources que nos ressources peuvent recevoir.
Si nous dĂ©veloppons un serveur qui doit ĂȘtre accessible
https://mywebsite.com
, nous devons ajouter ce domaine Ă l'en-tĂȘte Access-Control-Allow-Origin
.
GĂ©nial. Cet en-tĂȘte est maintenant ajoutĂ© Ă la rĂ©ponse du serveur envoyĂ©e au client. EPP ne nous empĂȘche plus de recevoir des ressources
https://api.mywebsite.com
via des requĂȘtes envoyĂ©es depuis https://mywebsite.com
.
Le mécanisme CORS du navigateur vérifie que les valeurs d'en
Access-Control-Allow-Origin
-tĂȘte de rĂ©ponse et d'en-tĂȘte de demande correspondent Origin
.
Dans ce cas, la source de notre requĂȘte est
https://www.mywebsite.com
l'en-tĂȘte de rĂ©ponse spĂ©cifiĂ© dans la liste Access-Control-Allow-Origin
.
Excellent. Nous pouvons désormais obtenir des ressources d'autres sources. Que se passe-t-il si nous essayons de le faire à partir d'une source non répertoriée dans
Access-Control-Allow-Origin
?
Oui, CORS a bloqué l'accÚs aux ressources.
The 'Access-Control-Allow-Origin' header has a value
'https://www.mywebsite.com' that is not equal
to the supplied origin.
Dans ce cas, la source n'est
https://www.anotherwebsite.com
pas répertoriée dans Access-Control-Allow-Origin
. CORS a refusé avec succÚs les données demandées.
CORS vous permet de spécifier les
*
sources autorisées en tant que valeur. Cela signifie que les ressources seront disponibles pour n'importe quelle source, alors soyez prudent.
Access-Control-Allow-Origin
Est l'un des nombreux titres que nous pouvons dĂ©finir. Le dĂ©veloppeur back-end peut configurer CORS pour autoriser (refuser) des requĂȘtes spĂ©cifiques.
Une autre rubrique courante est
Access-Control-Allow-Methods
. CORS autorise uniquement les demandes provenant d'autres sources qui ont été envoyées à l'aide des méthodes spécifiées.
Dans ce cas, seules les requĂȘtes envoyĂ©es Ă l'aide des mĂ©thodes GET, POST ou PUT sont autorisĂ©es. D'autres mĂ©thodes comme PATCH ou DELETE seront bloquĂ©es.
CORS les traite d'une maniĂšre spĂ©ciale lorsqu'il s'agit de requĂȘtes envoyĂ©es Ă l'aide des mĂ©thodes PUT, PATCH et DELETE. Ces requĂȘtes "dĂ©licates" sont parfois appelĂ©es requĂȘtes de contrĂŽle en amont.
Demandes préliminaires
CORS fonctionne avec deux types de demandes: simples et provisoires. Ce qu'est une requĂȘte dĂ©pend de certaines de ses valeurs.
Une requĂȘte est simple si elle est envoyĂ©e Ă l'aide des mĂ©thodes GET ou POST et ne contient pas d'en-tĂȘtes supplĂ©mentaires. Toute autre demande est prĂ©liminaire.
D'accord, mais que signifie la pré-demande et pourquoi de telles demandes sont-elles nécessaires?
Avant d'envoyer la requĂȘte proprement dite, le client envoie une requĂȘte prĂ©liminaire au serveur avec des informations sur la requĂȘte rĂ©elle: sur sa mĂ©thode, des en-tĂȘtes supplĂ©mentaires, notamment
Access-Control-Request-*
, etc.
Le serveur reçoit une requĂȘte provisoire et envoie une rĂ©ponse provisoire vide contenant des en-tĂȘtes CORS. Le navigateur reçoit une rĂ©ponse provisoire et vĂ©rifie si la demande rĂ©elle sera autorisĂ©e.
Si tel est le cas, le navigateur envoie la demande réelle et reçoit les données en retour.
Sinon, CORS bloquera la prĂ©-demande et la demande rĂ©elle ne sera pas envoyĂ©e. Les prĂ©-demandes sont un excellent moyen d'empĂȘcher l'accĂšs et la modification des ressources sur le serveur. Cela protĂšge le serveur des demandes potentiellement indĂ©sirables provenant d'autres sources.
Pour rĂ©duire le nombre de requĂȘtes rĂ©pĂ©tĂ©es, nous pouvons mettre en cache la rĂ©ponse provisoire en ajoutant un en-tĂȘte
Access-Control-Max-Age
Ă la requĂȘte CORS. Cela Ă©vite de renvoyer la demande prĂ©liminaire.
Identifiants
Les cookies, les en-tĂȘtes d'autorisation et les certificats TLS sont installĂ©s par dĂ©faut uniquement pour les demandes provenant d'une seule source. Cependant, nous pouvons avoir besoin d'utiliser ces autorisations dans une demande provenant d'une autre source. Nous souhaitons peut-ĂȘtre inclure des cookies dans la demande que le serveur peut utiliser pour identifier l'utilisateur.
Bien que CORS ne contienne pas d'autorisations par dĂ©faut, nous pouvons changer cela avec un en-tĂȘte
Access-Control-Allow-Credentials
.
Si nous voulons inclure des cookies et d'autres en-tĂȘtes d'autorisation dans notre demande Ă partir d'une autre source, nous devons dĂ©finir le champ sur une
withCredentials
valeur true
dans la demande et ajouter l'en-tĂȘte Access-Control-Allow-Credentials
à la réponse.
C'est fait, nous pouvons maintenant inclure des informations d'identification dans nos demandes provenant d'une autre source.
J'espÚre que l'article vous a été utile. Merci de votre attention.