Contextualisons…
Avant d’aller plus loin, mettons un peu de contexte. Vous le savez bien, le web a une obsession : la sécurité. On ne veut pas que n’importe qui puisse accéder aux données de n’importe où. Imaginez que vous soyez chez vous, peinard, et que votre voisin se pointe pour fouiller vos placards sous prétexte qu’il a envie de sucre pour son café. Eh bien, c’est exactement ce que les navigateurs essaient de prévenir avec le CORS ! On veut s’assurer que si quelqu’un tente d’accéder à notre application depuis un autre domaine (ou origine), ce soit pour des raisons valides et contrôlées.
Le SOP (Same-Origin Policy)
Avant de comprendre le CORS, il faut parler du grand frère protecteur, le SOP (Same-Origin Policy). Le SOP, c’est ce principe de base qui impose que chaque requête reste cloîtrée dans son domaine d’origine. Par exemple, si mon site est sur mon-site.com
, eh bien, il ne devrait en théorie faire des requêtes qu’à lui-même, mon-site.com. Autant dire que ce serait d’un ennui mortel si on devait se limiter à ça. C’est là que le CORS entre en scène pour nous permettre d’échanger gentiment entre domaines.
Mais au fait, qu’est-ce que le CORS ?
Le CORS est une couche de sécurité ajoutée pour que deux domaines différents puissent échanger des données sans que tout le web se transforme en Far West. En gros, quand on veut interagir avec un serveur sur un autre domaine (par exemple api.superdata.com
depuis notre domaine mon-site.com
), le navigateur envoie une petite requête pour demander la permission, un peu comme un ado qui demande s’il peut emprunter la voiture de papa. Le serveur doit alors répondre s’il accepte cette demande ou non, et c’est là que les choses peuvent vite se compliquer.
La requête d’options : preflight
Quand on parle de CORS, il est impossible d’ignorer la requête preflight. Ce petit message est envoyé automatiquement par le navigateur pour voir si le serveur est open bar sur les requêtes venues d’ailleurs. C’est un OPTIONS request, et c’est souvent à ce moment que les déboires commencent, car si le serveur n’a pas été bien configuré, il répondra juste un bon vieux 403 Forbidden
. Le navigateur nous le balance en pleine face, accompagné d’un beau message d’erreur du type “CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource”…
Les headers du CORS
Il est temps de faire la connaissance de nos amis les headers, ces petits messagers du CORS. On en a quelques-uns à connaître, qui font tout le travail de communication pour nous :
Access-Control-Allow-Origin
: ce header indique quels domaines ont le droit de jouer avec les ressources du serveur. Si on met*
, c’est open bar (mais dangereux). Si on met un domaine spécifique, seules les requêtes venant de ce domaine seront acceptées.Access-Control-Allow-Methods
: ce header liste les méthodes HTTP que le serveur accepte pour les requêtes cross-origin (GET, POST, PUT, DELETE, etc.).Access-Control-Allow-Headers
: ici, on définit les headers qu’une requête peut inclure, genreContent-Type
,Authorization
, et tout ce qui permet de passer de l’info critique.Access-Control-Allow-Credentials
: celui-là est essentiel si on veut passer des cookies ou des informations d’authentification entre domaines. Attention, il ne fonctionne que si l’Access-Control-Allow-Origin
n’est pas*
.Access-Control-Max-Age
: ce header dit au navigateur combien de temps il peut mettre en cache la réponse du preflight avant de refaire une demande d’autorisation. Histoire d’éviter de saturer le serveur.
Mais… pourquoi ça marche pas ?? 😡
Voici quelques cas classiques d’erreurs qui peuvent vous faire douter de tout ce que vous connaissez :
- Le serveur ne répond pas avec les bons headers : Si le serveur ne renvoie pas les headers corrects, bye-bye le cross-origin. Vérifiez que tous les headers sont bien là, sinon, c’est retour à la case départ.
- La requête avec cookies ? N’essayez même pas sans credentials : Les cookies, c’est bien mignon, mais il faut activer les credentials, sinon le navigateur n’en voudra pas.
- Le fameux wildcard (
*
) : Parfois, on se dit qu’en mettant*
, ça va résoudre tous les problèmes. Spoiler : ça en résout certains, mais ça en crée d’autres, surtout si on essaie de passer des cookies en même temps. - Un serveur qui fait de la rétention d’info : Si le serveur garde le silence sur l’un des headers CORS, la requête échouera, laissant le développeur face à une énigme digne de Sherlock Holmes.
Les solutions ? Parlons configuration serveur 🧐
Maintenant que vous avez identifié le problème, il est temps de prendre des mesures. Selon votre stack, voici quelques approches courantes :
- En Node.js (Express) : Utilisez le middleware
cors
:
const cors = require('cors'); app.use(cors({ origin: 'https://votre-domaine.com', methods: 'GET,POST', credentials: true }));
Avec ça, Express gère la plupart des headers nécessaires, et vous voilà tranquille.
- En PHP : Utilisation d’un
header
:
header("Access-Control-Allow-Origin: https://votre-domaine.com"); header("Access-Control-Allow-Methods: GET, POST"); header("Access-Control-Allow-Headers: Content-Type");
- En NGINX : CORS se gère aussi directement dans la configuration du serveur :
location /api/ { add_header 'Access-Control-Allow-Origin' 'https://votre-domaine.com'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization'; }
En gros… le CORS, c’est un peu comme un videur à l’entrée d’un club : il choisit qui a le droit de rentrer et sous quelles conditions. Ça peut sembler lourd, mais avec les bons headers et une configuration serveur correcte, vous avez tous les outils pour éviter les prises de tête. Pensez bien aux headers, testez votre preflight 😉