Pular para o conteúdo principal

JWT et cookies HttpOnly

Les jetons d'authentification sont déposés par le backend dans des cookies HttpOnly, illisibles par JavaScript. Le frontend ne les stocke plus dans localStorage : une faille XSS ne peut donc pas les voler.

Durées, routes et gestion des clés : voir Authentification JWT.

Cookies posés par le backend​

CookieContenuCheminDuréeAttributs
BEARERjeton d'accès JWT/1 heureHttpOnly ; Secure et SameSite=Strict en HTTPS, Lax en HTTP local
REFRESH_TOKENjeton de rafraîchissement/api/token30 joursidem
XSRF-TOKENjeton anti-CSRF/1 heure, renouvelélisible par JavaScript, par construction ; mêmes Secure et SameSite

Ils sont posés par JWTCookieSubscriber sur les réponses de connexion, de vérification 2FA, de lien magique et de rafraîchissement, et effacés sur POST /api/token/invalidate. Le corps de la réponse de connexion contient encore le jeton, pour les clients en ligne de commande.

Ordre de lecture du jeton​

  1. Cookie BEARER (navigateur).
  2. En-tête Authorization: Bearer … (scripts, outils, intégrations).

Le jeton de rafraîchissement est lu de la même façon : cookie REFRESH_TOKEN, sinon champ refresh_token du corps.

Protection CSRF​

Un cookie part automatiquement avec toute requête vers le domaine. Pour qu'un site tiers ne puisse pas déclencher d'action au nom de l'utilisateur, les mutations (POST, PUT, PATCH, DELETE) authentifiées par cookie doivent porter l'en-tête X-CSRF-TOKEN égal au cookie XSRF-TOKEN (CsrfProtectionSubscriber). Le client Axios du frontend l'ajoute de lui-même.

Exemptées : connexion, vérification 2FA, rafraîchissement, déconnexion, mot de passe oublié, lien magique, santé et routes publiques (/api/public/, /api/cms/public/). Les appels authentifiés par l'en-tête Authorization ne sont pas concernés.

La vérification est active par défaut ; CSRF_ENABLED=false la coupe, en développement seulement.

Côté frontend​

Le client Axios (frontend/src/services/api/client.ts) envoie les cookies (withCredentials: true) et garde le jeton d'accès en mémoire seulement. Au rechargement de la page, il appelle /api/token/refresh avant la première requête : le cookie REFRESH_TOKEN suffit à rétablir la session.

Vérifier​

Dans les outils de développement du navigateur, onglet Application → Cookies : BEARER et REFRESH_TOKEN doivent apparaître avec la case HttpOnly cochée, et Secure sur les serveurs.

curl -si -X POST https://sig-preprod.ucp-pch.org/api/login \
-H "Content-Type: application/json" \
-d '{"email":"<EMAIL>","password":"<MOT_DE_PASSE>"}' | grep -i "^set-cookie"