Gestion de CORS dans les applications Web –
CORS est un mécanisme de navigateur qui permet aux serveurs de spécifier les origines tierces qui peuvent leur demander des ressources. C’est une protection de sécurité qui aide à empêcher les sites malveillants de voler des données appartenant à d’autres origines.
CORS signifie Cross-Origin Resource Sharing. Lorsque CORS est utilisé pour charger une ressource, le navigateur envoie généralement un « preflight » HTTP OPTIONS
demander. Le serveur doit répondre en précisant les origines avec lesquelles il va interagir. Il peut également définir des contraintes supplémentaires, telles que les en-têtes HTTP qui peuvent être envoyés.
Le navigateur vérifie l’origine actuelle et la requête sortante par rapport aux spécifications du serveur. La demande est autorisée à se poursuivre si tous les contrôles sont réussis. Dans le cas contraire, la demande initiale sera annulée. Vous voyez un avertissement dans la console lorsque cela se produit.
Sommaire
Quand CORS est utilisé
Les navigateurs appliquent CORS pour les requêtes Ajax et Fetch. Le mécanisme sera également utilisé pour les polices Web, les textures WebGL et les dessins d’images de toile avec drawImage()
. Toute demande éligible à une origine tierce nécessitera un échange CORS pour avoir lieu.
Le CORS ne sera pas appliqué si la demande est considérée comme « simple ». Une simple demande doit être GET
, HEAD
ou alors POST
avec un type de contenu de text/plain
, application/x-www-form-urlencoded
ou alors multipart/form-data
. Les seuls en-têtes de requête simple autorisés sont Accept
, Accept-Language
, Content-Language
et Content-Type
.
Si la demande ne répond pas à tous les critères ci-dessus, un échange CORS sera lancé par les navigateurs modernes. Il est important de reconnaître que CORS est une technologie basée sur un navigateur – vous ne rencontrerez jamais CORS en faisant des demandes manuellement, comme avec curl
dans votre terminal.
Les échanges CORS n’envoient pas toujours un OPTIONS
demande de contrôle en amont. Un contrôle en amont est utilisé lorsque la demande provoquerait des « effets secondaires » sur le serveur. C’est généralement le cas pour les méthodes de requête autres que GET
.
Imaginez un POST
demande à /api/users/create
. Le serveur créerait toujours un nouvel utilisateur, mais le navigateur pourrait refuser l’accès à la réponse si la demande était soumise au CORS. En envoyant un OPTIONS
demande d’abord, le serveur a la possibilité de refuser explicitement la réel demander. Cela garantit que le compte d’utilisateur n’est pas réellement créé.
Gestion CORS côté client
Bien que CORS soit une technologie de navigateur, vous ne pouvez pas l’influencer directement avec le code côté client. Cela empêche les scripts malveillants de contourner les protections CORS pour charger des données à partir de domaines tiers.
CORS est généralement transparent, vous ne saurez donc pas qu’il fonctionne. Si un échange CORS échoue, votre code JavaScript verra une erreur de réseau générique. Il n’est pas possible d’obtenir des détails précis sur ce qui s’est mal passé, car cela constituerait un risque pour la sécurité. Les détails complets sont enregistrés dans la console.
Le seul moyen de résoudre un échec CORS est de s’assurer que votre serveur envoie les en-têtes de réponse corrects. Voyons maintenant comment cela se fait.
Manipulation CORS côté serveur
Vous devez d’abord vous assurer que votre serveur gère OPTIONS
demandes correctement. Vous devrez peut-être créer une nouvelle route dans votre framework Web. Vous devrez généralement accepter OPTIONS
demandes à chaque point de terminaison pouvant recevoir une demande d’origine croisée d’un navigateur. La réponse n’a pas besoin d’avoir un corps mais doit inclure des en-têtes spécifiques qui indiquent au navigateur comment procéder.
Commencez par ajouter le Access-Control-Allow-Origin
entête. Cela spécifie l’origine tierce qui est autorisée à communiquer avec votre point de terminaison. Une seule origine peut être spécifiée ; vous pouvez gérer plusieurs origines en définissant dynamiquement la valeur de l’en-tête sur l’origine à partir de laquelle la demande a été envoyée. Vous pouvez obtenir l’origine actuelle à partir du Origin
en-tête de demande.
Access-Control-Allow-Origin
accepte *
comme valeur générique spéciale. Cela permettra aux requêtes CORS de tout origines. Faites attention lorsque vous utilisez ceci – être spécifique avec les origines autorisées vous donne plus de contrôle et empêche les scripts malveillants de demander des données à votre serveur.
Access-Control-Allow-Origin
doit être inclus dans la réponse de votre serveur à la demande réelle, ainsi que le OPTIONS
réponse. Une fois cet en-tête unique configuré, un échange de base avec un client navigateur tiers sera autorisé.
Les requêtes CORS ne prennent généralement en charge que les en-têtes de requête « simples » répertoriés ci-dessus. Si vous devez utiliser un autre en-tête, tel que Authorization
ou un en-tête personnalisé, votre serveur devra l’autoriser explicitement dans la réponse de contrôle en amont.
Met le Access-Control-Allow-Headers
entête. Sa valeur doit être une liste de noms d’en-tête séparés par des virgules qui seront acceptés avec la vraie demande.
Access-Control-Allow-Headers: Authorization, X-Custom-Header
Le navigateur permettrait désormais une requête avec soit le Authorization
ou alors X-Custom-Header
en-têtes pour continuer.
Lorsque le navigateur envoie une demande de contrôle en amont CORS, il enverra le Access-Control-Request-Headers
entête. Celui-ci contient la liste des en-têtes qui seront envoyés avec la demande réelle. Votre code serveur peut utiliser ces informations pour déterminer comment répondre à la demande de contrôle en amont.
Limitation à des méthodes de requête spécifiques
De la même manière que pour la spécification des en-têtes de requête, les points de terminaison du serveur peuvent définir quelles méthodes HTTP doivent être autorisées pour l’origine croisée. Met le Access-Control-Allow-Methods
en-tête sous forme de liste de noms de méthodes séparés par des virgules.
Access-Control-Allow-Methods: GET, POST, DELETE
Le navigateur envoie le Access-Control-Request-Method
en-tête avec les contrôles en amont CORS. Cela permet à votre serveur de connaître la méthode HTTP qui sera utilisée pour effectuer la requête finale.
Cookies et identifiants
Les requêtes CORS n’envoient normalement pas de cookies car ils pourraient contenir des informations d’identification sensibles identifiant l’expéditeur. Si vous devez inclure des cookies avec une requête cross-origin, vous devez explicitement l’activer dans votre code côté client :
fetch("https://localhost/demo", {
mode: "cors",
credentials: "include"
});
De plus, le serveur doit définir le Access-Control-Allow-Credentials: true
en-tête de réponse pour signaler son accord que les cookies authentifiés peuvent être échangés.
Lors de l’utilisation Access-Control-Allow-Credentials,
toi ne peux pas utilisez le caractère générique (*
) avec Access-Control-Allow-Origin
. Le serveur doit spécifier une origine explicite à la place pour protéger la confidentialité de l’utilisateur. Si le caractère générique est envoyé, le navigateur échouera la demande avec une erreur CORS.
Mise en cache en amont
SCRO OPTIONS
les vols en amont ajoutent une surcharge à chaque demande que vous faites. Bien que le retard soit à peine perceptible sur une bonne connexion réseau, il est néanmoins inutile lorsque vous appelez le même point de terminaison plusieurs fois de suite.
Vous pouvez demander au navigateur de mettre en cache les réponses de contrôle en amont en définissant le Access-Control-Max-Age
entête. La valeur doit être la durée en secondes pendant laquelle le navigateur est autorisé à mettre en cache la réponse. Les demandes ultérieures au même point de terminaison au cours de la période donnée n’enverront pas de contrôle en amont CORS.
Conclusion
Le CORS peut sembler déroutant la première fois que vous le rencontrez. C’est une technologie de navigateur qui est contrôlée par les réponses du serveur. CORS est inévitable et pourtant incontrôlable, à moins que vous n’ayez accès au code côté serveur avec lequel vous interagissez.
La mise en œuvre réelle de CORS est assez simple. Assurez-vous que votre API ou CDN envoie les bons en-têtes de réponse, notamment Access-Control-Allow-Origin
. Vous disposerez alors d’une communication cross-origin sécurisée qui vous aidera à vous prémunir contre les mauvais acteurs.