Développement

Comment décoder et déboguer un JWT

Un JSON Web Token se compose simplement de trois parties encodées en Base64URL. Une fois que vous savez les lire, la plupart des erreurs « invalid token » s’expliquent en quelques secondes. Ce guide vous montre comment décoder un JWT, vérifier les claims qui posent le plus souvent problème, et éviter les erreurs qui transforment les JWT en failles de sécurité.

Débutant · 7 min de lecture · Mis à jour le 30 octobre 2026

Comment décoder et déboguer un JWT

De quoi est composé un JWT

Un JWT ressemble à xxxxx.yyyyy.zzzzz. Les trois parties, séparées par des points, sont :

  1. En-tête (Header) — du JSON contenant l’algorithme de signature (alg) et le type de jeton, par exemple {"alg":"HS256","typ":"JWT"}.
  2. Charge utile (Payload) — du JSON contenant les claims : à qui le jeton est destiné et à quelle période il est valide.
  3. Signature — un hash des deux premières parties, calculé avec un secret (HMAC) ou une clé privée (RSA, ECDSA).

Les deux premières parties sont uniquement encodées, et non chiffrées. Toute personne qui détient le jeton peut les lire : ne mettez donc jamais de mots de passe ou de données personnelles dans la charge utile d’un JWT.

Décoder un jeton

Collez le jeton dans le JWT Decoder : il affiche l’en-tête, la charge utile et chaque horodatage sous forme de date lisible. L’outil fonctionne dans votre navigateur, donc vos jetons de production ne sont envoyés nulle part. Pour le faire manuellement, décodez chaque partie en Base64URL — remplacez - par +, _ par /, ajoutez le padding — ou, avec Node :

const [header, payload] = token.split('.').slice(0, 2)
  .map(part => JSON.parse(Buffer.from(part, 'base64url').toString()));
console.log(header, payload);

Les claims qui posent le plus souvent problème

ClaimSignificationErreur typique
expExpiration, en secondes Unix« jwt expired » — vérifiez aussi les horloges du serveur et du client
nbfNon valide avantUn jeton utilisé quelques secondes trop tôt, car l’horloge de l’émetteur est en avance
iatÉmis leRejeté comme « émis dans le futur » après une dérive d’horloge
audAudience à laquelle le jeton est destinéUn jeton prévu pour une API envoyé à une autre — le vérificateur doit le contrôler
issÉmetteurÉmetteurs de développement et de production confondus

Les horodatages sont exprimés en secondes, et non en millisecondes. Si une date d’expiration correspond à l’an 55 000, quelqu’un a écrit Date.now() au lieu de Math.floor(Date.now() / 1000). Le Unix Timestamp Converter permet de le vérifier. La plupart des bibliothèques acceptent une petite tolérance d’horloge (30 à 60 secondes) pour absorber les écarts entre serveurs.

Pourquoi « invalid signature » ?

  • Mauvais secret ou mauvaise clé — la cause la plus fréquente. Vérifiez la variable d’environnement du serveur qui vérifie le jeton, et pas seulement celle du serveur qui le signe.
  • Mauvais algorithme — un jeton signé en RS256 vérifié en HS256, ou l’inverse.
  • Le jeton a été modifié — changer un seul caractère de la charge utile casse la signature, et c’est bien le but.
  • Rotation des clés — les clés de l’émetteur ont changé. Avec JWKS, faites correspondre le kid de l’en-tête à une clé publiée.

Pour vérifier un jeton HS256 à la main, calculez le HMAC-SHA256 de header.payload avec le secret à l’aide du HMAC Generator, puis comparez-le, encodé en Base64URL, à la troisième partie.

Erreurs de sécurité à éviter

  • Décoder n’est pas vérifier. Ne faites jamais confiance aux claims issus de jwt.decode() ; utilisez la fonction de vérification de votre bibliothèque avec une liste explicite d’algorithmes autorisés.
  • Rejetez alg: none et figez l’algorithme — ne laissez jamais le jeton choisir comment il est contrôlé.
  • Gardez des jetons de courte durée (quelques minutes pour les jetons d’accès) et utilisez des refresh tokens pour les sessions longues ; un JWT ne peut pas être révoqué avant son expiration sans état supplémentaire côté serveur.
  • Ne stockez pas les jetons dans le localStorage si une faille XSS pourrait les lire ; un cookie HttpOnly, Secure, SameSite est plus sûr pour les applications web.

Besoin d’un jeton de test avec des claims précis ? Créez-le avec le JWT Encoder.

Questions fréquentes

Quelqu’un peut-il lire mon JWT ?
Oui. L’en-tête et la charge utile sont seulement encodés en Base64URL. La signature empêche de les modifier, mais pas de les lire. Utilisez JWE (jetons chiffrés) si le contenu doit rester secret.
Est-il sûr de coller un jeton dans un décodeur en ligne ?
Seulement si l’outil fonctionne localement. Le JWT Decoder de devpack décode dans votre navigateur et n’envoie rien ; évitez les outils qui transmettent le jeton à un serveur, surtout pour les jetons de production.
Que signifie « jwt malformed » ?
La chaîne n’est pas constituée de trois parties Base64URL séparées par des points. Cela vient souvent du mot « Bearer » resté devant le jeton, ou d’un jeton tronqué lors de la copie.

À lire aussi