MAISON CODE .
/ Tech · Security · Auth · JWT · Backend

Authentification JWT : sécurité sans état

Sessions contre JWTS. Le débat est sans fin. Quand utiliser les jetons Web JSON, comment les stocker en toute sécurité (HttpOnly) et comment gérer la rotation.

AB
Alex B.
Authentification JWT : sécurité sans état

Le débat session vs jeton

Authentification de session (Le Classique) :

  1. L’utilisateur se connecte.
  2. Le serveur crée un ID de session (sess_123). Le stocke en mémoire/Redis.
  3. Le serveur envoie l’ID au cookie client.
  4. Le client envoie un cookie.
  5. Le serveur recherche « sess_123 » dans Redis. Recherche “L’utilisateur est Bob”. Avantages : Révocable (Supprimer de Redis = Utilisateur déconnecté). Inconvénients : avec état. Vous avez besoin de Redis. Plus difficile à étendre à travers les régions.

Authentification JWT (le moderne) :

  1. L’utilisateur se connecte.
  2. Le serveur crée un jeton Web JSON. Contient { id : 1, nom : "Bob" }. Le signe avec une clé secrète.
  3. Le serveur envoie JWT au client.
  4. Le client envoie JWT.
  5. Le serveur vérifie la signature. Recherche “L’utilisateur est Bob”. Avantages : Apatride. Aucune recherche de base de données requise. “Le jeton est la session”. Inconvénients : Irrévocable. En cas de vol, valable jusqu’à expiration.

Pourquoi Maison Code en parle

Chez Maison Code, nous construisons des microservices et des applications mobiles. Les sessions sont terribles pour les applications mobiles (les cookies sont difficiles). Les sessions sont terribles pour les microservices (le partage d’une instance Redis sur 10 services est un couplage). JWT est le passeport universel. Le service A peut vérifier le jeton émis par le service d’authentification simplement en connaissant la clé publique. Nous mettons en œuvre des flux JWT stricts pour activer nos architectures sans tête.

L’anatomie d’un JWT

Trois parties, séparées par des points. En-tête.Charge utile.Signature.

  1. En-tête : Algorithme (HS256).
  2. Charge utile : données (sub : 123, exp : 17000000).
  3. Signature : Hash(En-tête + Charge utile + Secret).

Critique : la charge utile est codée en Base64, NON chiffrée. Tout le monde peut le lire (atob(token)). Règle : Ne mettez jamais de secrets dans le JWT. Aucun mot de passe. Pas de cartes de crédit. Uniquement les ID d’utilisateur et les rôles publics.

Où le stocker ? (La Guerre Sainte)

Option 1 : stockage local

  • Facile (localStorage.setItem('token', t)).
  • Vulnérable à XSS. Si l’attaquant exécute JS, il lit le jeton.

Option 2 : Cookie HttpOnly

  • Sécurisé. JS limite l’accès.
  • Vulnérable au CSRF.
  • Nécessite SameSite=Strict.

Verdict du code de la maison : Cookie HttpOnly. CSRF est plus facile à atténuer (SameSite) que XSS. Pour les applications mobiles, utilisez le stockage sécurisé (porte-clés).

Le modèle de jeton d’accès/jeton d’actualisation

Pour résoudre le problème « Irrévocable ».

  1. Jeton d’accès : courte durée de vie (5 minutes). Utilisé pour appeler l’API.
  2. Jeton d’actualisation : Longue durée de vie (7 jours). Stocké en toute sécurité (HttpOnly/DB). Utilisé uniquement pour obtenir un nouveau jeton d’accès.

Flux :

  1. Le client effectue un appel API avec le jeton d’accès.
  2. Le serveur indique « 401 expiré ».
  3. Le client appelle /refresh-token avec Refresh Token.
  4. Le serveur vérifie la base de données. “Ce jeton d’actualisation est-il bloqué ? Non.”
  5. Le serveur émet un nouveau jeton d’accès. Sécurité : Si le jeton d’accès est volé, il fonctionne pendant 5 minutes. Si vous bannissez l’utilisateur, vous supprimez le jeton d’actualisation de la base de données. Ils sont verrouillés dans un délai maximum de 5 minutes.

Algorithme : HS256 contre RS256

  • HS256 (Symétrique) : Le serveur signe et vérifie avec le même secret. Rapide. Simple pour les monolithes.
  • RS256 (Asymétrique) : Le service d’authentification signe avec la clé privée. D’autres services vérifient avec la clé publique.
    • Ceci est crucial pour les microservices. Le “Product Service” peut vérifier l’utilisateur sans connaître le secret du service d’authentification.

Le point de vue du sceptique

“Les séances sont plus simples.” Contre-point : Oui, pour un monolithe avec un seul serveur. Essayez de faire des sessions lorsque vous avez un frontend Next.js sur Vercel Edge Network et un backend Go sur AWS. La latence de « Checking Redis » tue les performances Edge. JWT permet de vérifier l’authentification au bord (vérifier la signature en 1 ms) sans déclenchement de la base de données.

##FAQ

Q : Puis-je invalider manuellement un JWT ? R : Non. C’est justement le problème. Vous pouvez implémenter une « liste noire » (stocker les identifiants JWT invalides dans Redis), mais vous avez ensuite réinventé les sessions. Utilisez plutôt des délais d’expiration courts.

Q : Quelle peut être la taille d’un JWT ? R : Gardez-le petit. Il est envoyé dans chaque en-tête HTTP. Si vous y mettez 50 autorisations, vous ralentissez chaque demande.

10. Rotation des jetons (la chaîne de rafraîchissement)

Les jetons de rafraîchissement standard ont un défaut : en cas de vol, le voleur y a accès pendant 7 jours. Solution : Actualiser la rotation des jetons.

  1. Le client envoie le jeton d’actualisation A.
  2. Le serveur renvoie le jeton d’accès B ET Nouveau jeton d’actualisation C.
  3. Le serveur supprime le jeton d’actualisation A. Si le voleur essaie à nouveau d’utiliser “Old Refresh Token A” -> Alarme de sécurité. Le serveur détecte la réutilisation d’un jeton révoqué. Cela invalide immédiatement toute la « famille de jetons » (A, C et tous les descendants). Le voleur est immédiatement mis en lock-out. Le véritable utilisateur est invité à se reconnecter.

11. JWKS (ensembles de clés Web JSON)

Comment faire pivoter les clés de signature ? Vous ne pouvez pas regrouper la clé publique dans les applications chaque semaine. Solution : point de terminaison JWKS (/.well-known/jwks.json). Le serveur d’authentification publie ses clés publiques sur une URL. Le serveur de ressources les récupère dynamiquement (et les met en cache). Si vous soupçonnez une compromission de clé, vous faites pivoter la clé sur le serveur d’authentification, mettez à jour le JWKS et tout le monde récupère la nouvelle clé en 5 minutes.

12. OAuth 2.1 et l’avenir

JWT n’est que le format du jeton. OAuth 2.0 est le flux. Le secteur passe à OAuth 2.1 (Consolidation des meilleures pratiques).

  • Plus de flux implicite (jeton d’accès dans le hachage d’URL).
  • PKCE (Proof Key for Code Exchange) est obligatoire. Nous implémentons désormais PKCE même pour les applications Web côté serveur. Il empêche les attaques par « injection de code d’autorisation ».

13. Authentification machine à machine (identifiants client)

Que se passe-t-il si le « travail Cron A » doit appeler « l’API B » ? Il n’y a aucun utilisateur. Pas de mot de passe. Nous utilisons Client Credentials Flow. POST /token {client_id, client_secret }. Renvoie un JWT. Cela normalise Auth. Qu’il s’agisse d’un Utilisateur (sub : user_1) ou d’une Machine (sub : service_billing), l’API valide simplement la signature JWT. L’uniformité est la sécurité.

14. Conclusion

JWT est la monnaie du Web moderne. Comme l’argent, il doit être soigneusement frappé (Signature), stocké en toute sécurité (Coffre-fort) et vérifié pour les contrefaçons (Vérification). Ne lancez pas votre propre crypto. Utilisez des bibliothèques (jsonwebtoken, jose).

Authentification cassée ?

Si les utilisateurs se déconnectent de manière aléatoire ou si vous stockez des jetons dans LocalStorage, Maison Code peut sécuriser votre flux d’authentification. Nous mettons en œuvre des stratégies de rotation OAuth2, OIDC et JWT.



Des problèmes d’authentification ?

Nous sécurisons l’authentification sans état à l’aide de cookies JWT (modèle d’accès/actualisation) et HttpOnly pour protéger les identités sur les microservices. Embauchez nos architectes.