jwt debugging security authentication web-development

Résoudre l'erreur 'JWT expired' et les erreurs courantes de JSON Web Token

Un guide complet pour corriger les erreurs JWT telles que 'invalid signature', 'token expired' et 'malformed token'. Apprenez à déboguer les problèmes d'authentification.

Résoudre l'erreur "JWT expired" et les erreurs courantes de JSON Web Token : Guide Complet

Les JSON Web Tokens (JWT) sont la norme de l'industrie pour transmettre en toute sécurité des informations entre les parties sous forme d'objet JSON. Ils sont largement utilisés pour l'authentification et l'autorisation dans les applications web et mobiles modernes. Cependant, comme ils sont signés cryptographiquement et ont souvent des règles d'expiration strictes, ils peuvent être une source majeure de maux de tête lors du débogage.

Dans ce guide, nous allons décomposer les erreurs JWT les plus courantes, expliquer pourquoi elles se produisent et vous montrer comment les corriger.


1. Messages d'erreur JWT courants

Selon la bibliothèque que vous utilisez (comme jsonwebtoken dans Node.js), vous rencontrerez ces noms d'erreurs courants :

  • TokenExpiredError : Le jeton est valide mais son délai d'expiration est dépassé.
  • JsonWebTokenError: invalid signature : La signature du jeton ne correspond pas au secret/clé fourni.
  • JsonWebTokenError: jwt malformed : La chaîne fournie n'est pas une structure JWT valide.
  • JsonWebTokenError: jwt signature is required : Un jeton a été fourni sans la section de signature.
  • JsonWebTokenError: jwt invalid audience : La revendication aud dans le jeton ne correspond pas à la valeur attendue.

2. Principales causes et solutions

2.1 "TokenExpiredError" (JWT expired)

Tout JWT sécurisé doit avoir une revendication exp (expiration). Une fois que l'heure actuelle dépasse cette valeur, le jeton n'est plus valide.

Le symptôme : Les utilisateurs sont soudainement déconnectés, ou les requêtes API commencent à renvoyer des erreurs 401 Unauthorized avec le message jwt expired.

La solution :

  1. Refresh Tokens : Implémentez une stratégie de "Refresh Token" afin que les utilisateurs n'aient pas à se connecter manuellement à chaque expiration d'un jeton d'accès.
  2. Synchronisation de l'horloge : Assurez-vous que l'horloge de votre serveur est synchronisée via NTP. Même un décalage de quelques secondes peut causer des problèmes.
  3. Vérifiez iat et nbf : Assurez-vous que les revendications "émis à" (iat) et "pas avant" (nbf) sont également correctes.

2.2 "invalid signature" (invalid JWT signature)

Un JWT se compose de trois parties : En-tête (Header), Charge utile (Payload) et Signature. La signature est créée en hachant l'en-tête et la charge utile avec une clé secrète. Si ne serait-ce qu'un seul caractère de la charge utile change, ou si la mauvaise clé secrète est utilisée, la signature devient invalide.

La cause :

  • Utilisation du mauvais secret ou de la mauvaise public key pour vérifier le jeton.
  • Une discordance entre l'algorithme utilisé pour signer (ex: HS256) et pour vérifier (ex: RS256).
  • Le jeton a été altéré ou corrompu pendant la transmission.

La solution :

  • Vérifiez deux fois vos variables d'environnement pour la clé secrète.
  • Vérifiez que l'en-tête alg dans le JWT correspond à l'algorithme que vous utilisez pour la vérification.

2.3 "jwt malformed" ou "jwt decode failed"

Un JWT valide doit comporter trois parties séparées par des points (header.payload.signature). Si une partie est manquante ou si la chaîne n'est pas un Base64URL valide, elle est considérée comme malformée.

La cause :

  • Passage direct d'un préfixe "Bearer " à la bibliothèque (ex : atob("Bearer <token>")).
  • Copier-coller d'un jeton partiel.
  • Espaces blancs supplémentaires ou caractères invisibles dans la chaîne du jeton.

La solution : Assurez-vous de supprimer le préfixe Bearer avant de le passer à votre décodeur.

const token = authHeader.split(' ')[1]; // Extraire le jeton de "Bearer <token>"

2.4 "jwt invalid audience" ou "jwt invalid issuer"

Ces erreurs se produisent lorsque les revendications aud (audience) ou iss (émetteur) dans la charge utile ne correspondent pas aux valeurs attendues par votre serveur.

La solution : Assurez-vous que la configuration sur votre serveur d'authentification (ex : Auth0, Firebase ou le vôtre) correspond aux options de vérification dans le code de votre application.


3. Dépannage avancé

3.1 Inspection de la charge utile

Si vous obtenez une erreur de signature, la première étape consiste à inspecter la charge utile pour voir si elle contient les données attendues. Vous n'avez pas besoin de la clé secrète pour décoder et lire la charge utile (puisqu'elle est simplement encodée en Base64).

3.2 Attaques par confusion d'algorithme (Algorithm Confusion Attacks)

Assurez-vous que votre bibliothèque est configurée pour n'autoriser que les algorithmes spécifiques que vous attendez. Certaines anciennes bibliothèques étaient vulnérables à une attaque où un attaquant pouvait changer l'en-tête en alg: none, contournant la sécurité. Les bibliothèques modernes ont pour la plupart corrigé cela, mais définissez toujours explicitement vos algorithmes autorisés.

jwt.verify(token, secret, { algorithms: ['HS256'] });

4. Prévention et bonnes pratiques

  1. Jetons d'accès à courte durée : Gardez les jetons d'accès à courte durée de vie (ex : 15 minutes) et utilisez des jetons de rafraîchissement pour les sessions plus longues.
  2. Secrets sécurisés : Ne codez jamais votre secret JWT en dur. Utilisez des variables d'environnement et renouvelez-les périodiquement.
  3. Validez chaque requête : Ne faites jamais confiance à un JWT sans vérifier sa signature côté serveur.
  4. Utilisez HTTPS : Transmettez toujours les jetons via HTTPS pour empêcher les attaques d'interception de type "Man-in-the-Middle".

5. FAQ : Foire aux questions

Q : Puis-je lire les données d'un JWT sans le secret ?

R : Oui. L'en-tête et la charge utile sont simplement encodés en Base64URL, pas chiffrés. Quiconque possède le jeton peut lire les données. Ne mettez jamais d'informations sensibles comme des mots de passe ou des numéros de carte de crédit dans la charge utile d'un JWT.

Q : Quelle est la différence entre HS256 et RS256 ?

R : HS256 utilise une clé secrète unique pour la signature et la vérification (symétrique). RS256 utilise une clé privée pour signer et une clé publique pour vérifier (asymétrique), ce qui est plus sûr pour les systèmes distribués.

Q : Comment gérer une erreur "jwt expired" côté frontend ?

R : Capturez l'erreur 401 dans votre intercepteur API. Si l'erreur est "jwt expired", tentez d'appeler votre point de terminaison "refresh token". En cas d'échec, redirigez l'utilisateur vers la page de connexion.


6. Outil de vérification rapide

Vous avez des problèmes avec un jeton spécifique ? Utilisez notre Décodeur et débogueur JWT. Il vous permet de :

  • Décoder instantanément n'importe quel JWT pour voir son en-tête et sa charge utile.
  • Vérifier l'état d'expiration et les revendications comme iat, exp et nbf.
  • Identifier les jetons malformés (malformed tokens) et les problèmes d'encodage.
  • Valider les signatures (si vous fournissez votre clé secrète localement).

Erreurs associées

  • Résoudre les erreurs 'Unexpected token in JSON'
  • Comment corriger les erreurs 'invalid base64 string'
  • Résoudre les erreurs 'invalid regular expression'