Sévérité : MoyenneConception d'API REST

Appels API bloqués par le navigateur (CORS)

```text
Access to fetch at 'https://api.exemple.fr/v1/orders' from origin 'https://app.exemple.fr' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present.
```

Détecter

Le front web n'arrive plus à appeler l'API après son déplacement sur un nouveau domaine ; curl fonctionne parfaitement.

Symptômes

Le front web n'arrive plus à appeler l'API après son déplacement sur un nouveau domaine ; curl fonctionne parfaitement.

Environnement

Front sur https://app.exemple.fr, API sur https://api.exemple.fr derrière NGINX, authentification par cookie.

Cause racine

CORS est appliqué par le navigateur. Les requêtes avec cookie ou en-têtes personnalisés déclenchent un preflight OPTIONS ; l'API (ou le proxy) ne renvoie pas les en-têtes attendus, ou renvoie * alors que credentials: include l'interdit.

Diagnostic

curl -si -X OPTIONS https://api.exemple.fr/v1/orders \
  -H "Origin: https://app.exemple.fr" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: content-type"

Vérifier : Access-Control-Allow-Origin (origine exacte), Allow-Credentials: true, Allow-Methods, Allow-Headers, et que le preflight répond 204/200 sans authentification.

Solution

Configurer CORS dans l'application (liste blanche d'origines), ou dans NGINX pour la location API, en renvoyant l'origine exacte et Vary: Origin.

Commandes

if ($http_origin = "https://app.exemple.fr") { set $cors $http_origin; }
add_header Access-Control-Allow-Origin $cors always;
add_header Access-Control-Allow-Credentials true always;
add_header Vary Origin always;

Prévention

Liste d'origines en configuration par environnement, tests E2E navigateur (Playwright) en CI, ou même domaine pour front et API (proxy /api).