Developer Tools

Les tokens JWT expliqués : structure, sécurité et erreurs courantes

Comprenez le fonctionnement des JSON Web Tokens, leur contenu et les pièges de sécurité qui piègent les développeurs en production.

8 min de lecture

Cadenas de sécurité sur un circuit imprimé

Les JSON Web Tokens (JWTs) sont omniprésents — ils alimentent l'authentification dans les SPAs, les applications mobiles et les architectures microservices du monde entier. Pourtant, ils figurent aussi parmi les primitives de sécurité les plus mal comprises du développement web. Les utiliser incorrectement peut entraîner un contournement d'authentification, une élévation de privilèges, ou une prise de contrôle totale d'un compte.

Qu'est-ce qu'un JWT ?

Un JWT est une chaîne compacte et compatible URL qui encode un ensemble de claims — des assertions sur un utilisateur ou une session. Il ressemble à ceci :

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Il est composé de trois segments encodés en Base64URL séparés par des points :

  1. Header — l'algorithme et le type de token
  2. Payload — les claims (données utilisateur)
  3. Signature — la preuve cryptographique d'intégrité

Collez n'importe quel JWT dans notre JWT Decoder pour inspecter instantanément les trois parties sans passer par aucun serveur externe.

Anatomie d'un JWT

{
  "alg": "HS256",
  "typ": "JWT"
}

alg spécifie l'algorithme de signature. Valeurs courantes :

  • HS256 — HMAC avec SHA-256 (symétrique, secret unique)
  • RS256 — RSA avec SHA-256 (asymétrique, clé publique/privée)
  • ES256 — ECDSA avec SHA-256 (asymétrique, clés plus courtes)

Payload

{
  "sub": "user_abc123",
  "email": "alice@example.com",
  "role": "admin",
  "iat": 1711670400,
  "exp": 1711756800
}

Claims standards enregistrés :

Claim Signification
sub Sujet (à qui le token fait référence)
iss Émetteur (qui a créé le token)
aud Audience (qui doit l'accepter)
exp Date d'expiration (timestamp Unix)
iat Date d'émission (timestamp Unix)
nbf Pas avant (ne pas accepter avant cette date)

Signature

Pour HS256 :

HMAC-SHA256(base64url(header) + "." + base64url(payload), secret)

La signature prouve que le token n'a pas été altéré. Le payload n'est PAS chiffré — il est simplement encodé. N'importe qui peut le lire.

Ne stockez jamais de données sensibles comme des mots de passe ou des numéros de carte bancaire dans un payload JWT.

HS256 vs. RS256 : lequel choisir ?

HS256 utilise un secret partagé unique. Chaque service ayant besoin de vérifier les tokens doit posséder le même secret. Simple pour les applications monolithiques, mais dangereux dans les architectures multi-services — si un service est compromis, un attaquant peut forger des tokens.

RS256 utilise des clés asymétriques. Le serveur d'authentification signe avec une clé privée ; tous les autres services vérifient avec la clé publique. La compromission d'un service consommateur ne donne pas à un attaquant la capacité de forger des tokens. Privilégiez RS256 pour tout système composé de plusieurs services.

La vulnérabilité alg: none

L'une des attaques JWT les plus tristement célèbres. Certaines anciennes bibliothèques acceptaient un token avec "alg": "none" et sans signature — le considérant comme valide. Un attaquant pouvait ainsi forger :

{ "alg": "none" }

avec n'importe quel payload et contourner complètement l'authentification.

Correction : Spécifiez toujours explicitement les algorithmes autorisés dans votre bibliothèque JWT. N'acceptez jamais none.

// ❌ Dangereux
jwt.verify(token, secret);

// ✅ Sécurisé — accepte uniquement HS256
jwt.verify(token, secret, { algorithms: ["HS256"] });

Attaque par confusion d'algorithme

Une autre vulnérabilité critique : si votre bibliothèque détecte automatiquement l'algorithme à partir du header, un attaquant peut remplacer RS256 par HS256 et signer le token en utilisant la clé publique comme secret HMAC (qui est, par définition, publique).

Correction : Codez toujours en dur l'algorithme attendu. Ne faites jamais confiance au header alg.

Stockage des tokens : où conserver les JWTs

Stockage Risque XSS Risque CSRF Remarques
localStorage Élevé Aucun Accessible à tout JS de la page
sessionStorage Élevé Aucun Effacé à la fermeture de l'onglet
Cookie HTTP-only Aucun Moyen Idéal pour les apps web ; utilisez SameSite=Strict
Mémoire (variable) Faible Aucun Perdu au rechargement ; pour les SPAs

Pour les applications web, les cookies HTTP-only avec SameSite=Strict constituent l'option la plus sécurisée. Pour les applications natives, les API de stockage sécurisé (Keychain, Keystore) sont appropriées.

Expiration et refresh tokens

Des access tokens de courte durée (5 à 15 minutes) associés à des refresh tokens de longue durée constituent le schéma standard :

  1. L'utilisateur se connecte → le serveur émet un access token (15 min) + un refresh token (7 jours, stocké en base de données)
  2. Le client utilise l'access token pour les appels API
  3. Quand l'access token expire, le client envoie le refresh token → il reçoit un nouvel access token
  4. À la déconnexion, invalider le refresh token en base de données

Cela limite la fenêtre d'exposition en cas de vol d'un access token.

Révoquer des JWTs

Les JWTs sont sans état — une fois émis, ils sont valides jusqu'à leur expiration. Il s'agit d'un compromis. Options pour une révocation anticipée :

  • Liste de blocage — stockez les valeurs JTI (JWT ID) invalidées dans Redis. Vérifiez à chaque requête.
  • Expiration courte — des tokens de 5 minutes limitent le rayon d'impact.
  • Rotation des refresh tokens — détectez la réutilisation d'un token ayant déjà été roté comme signe de vol.

Débogage avec le JWT Decoder

Pour déboguer des problèmes d'authentification, utilisez notre JWT Decoder pour :

  • Inspecter le payload complet sans écrire une seule ligne de code
  • Vérifier les timestamps d'expiration dans un format lisible
  • Contrôler l'algorithme utilisé
  • Repérer des claims inattendus ou manquants

Tout le décodage s'effectue localement dans votre navigateur — vos tokens ne quittent jamais votre machine.

Liste de contrôle de sécurité JWT

  • Utiliser RS256 ou ES256 pour les architectures multi-services
  • Spécifier explicitement les algorithmes autorisés dans votre bibliothèque
  • Valider les claims exp, iss et aud à chaque requête
  • Stocker les tokens dans des cookies HTTP-only pour les applications web
  • Utiliser des durées de vie courtes pour les access tokens (15 min ou moins)
  • Implémenter la rotation des refresh tokens avec détection de réutilisation
  • Ne jamais placer de données sensibles dans le payload
  • Utiliser HTTPS partout — un token en clair équivaut à l'absence d'authentification

Les JWTs sont puissants et pratiques, mais leur niveau de sécurité dépend entièrement de leur implémentation. Comprenez la structure, connaissez les attaques, et votre couche d'authentification sera solide.