Comment décoder un JWT
Un JWT est composé de trois chaînes base64url séparées par des points : en-tête, payload et signature. Pour le décoder, coupez sur les points et décodez en base64url les deux premières parties ; chacune est un objet JSON. Aucune clé n’est nécessaire, car un JWT signé n’est pas chiffré. Le décodage ne prouve rien : seule la vérification de la signature avec le secret ou la clé publique de l’émetteur, plus le contrôle de exp, nbf, iss et aud, garantit que le jeton est authentique et encore valide.

Que contient un JWT ?
Prenons le jeton d’exemple public de la documentation JWT :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 .eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ .SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
La première partie se décode en {"alg":"HS256","typ":"JWT"} : le jeton est signé en HMAC-SHA256. La deuxième donne {"sub":"1234567890","name":"John Doe","iat":1516239022}. La troisième est la signature, des octets bruts encodés en base64url, qui n’a de sens que pour qui détient la clé.
Quels sont les claims courants ?
| Claim | Signification |
|---|---|
| sub | Sujet : à qui se rapporte le jeton, souvent un identifiant d’utilisateur |
| iss | Émetteur : qui a créé le jeton |
| aud | Audience : quelle API doit l’accepter |
| iat | Date d’émission, en secondes Unix (1516239022 = 18/01/2018 01:30:22 UTC) |
| nbf | Pas valide avant, en secondes Unix |
| exp | Expiration, en secondes Unix |
| scope / roles | Permissions (le nom varie selon le fournisseur) |
Comment déboguer une erreur 401 ?
Un appel d’API qui marchait hier renvoie 401. Décodez le jeton de l’en-tête Authorization et vérifiez dans l’ordre :
- exp : est-il dépassé ? La plupart des jetons d’accès vivent 5 à 60 minutes ; c’est la cause la plus fréquente.
- aud : désigne-t-il l’API appelée ?
- iss : vient-il du bon environnement ? Un jeton de préproduction échoue en production.
- scope ou roles : la permission nécessaire est-elle présente ?
- Décalage d’horloge : si iat ou nbf est quelques secondes dans le futur, les horloges ne sont pas d’accord.
Si tout semble correct, le problème vient probablement de la signature, par exemple une clé de signature renouvelée.
Quelles erreurs de sécurité faut-il éviter ?
- Faire confiance à un payload décodé. N’importe qui peut fabriquer un jeton avec "role": "admin" ; seule une signature vérifiée rend les claims fiables.
- Accepter alg "none" ou laisser le jeton choisir l’algorithme. Fixez l’algorithme attendu côté serveur.
- Mettre des secrets dans le payload. Un JWT signé est lisible par quiconque le possède.
- Coller un jeton actif dans un outil en ligne qui l’envoie à un serveur. Le décodeur JWT de ce site décode dans votre navigateur, sans rien envoyer.
Comment décoder un JWT ? Trois façons
- Dans le navigateur : collez le jeton dans le décodeur JWT. Il affiche l’en-tête et le payload en JSON, convertit iat, nbf et exp en dates et indique si le jeton a expiré. Rien n’est envoyé.
- Dans un terminal : prenez la partie du milieu, passez du base64url au base64 (remplacez - par + et _ par /, ajoutez le remplissage =), lancez
base64 -d, puis envoyez le résultat àjq. - Dans le code : la plupart des bibliothèques JWT ont une fonction de décodage sans vérification, à réserver au débogage. En production, appelez la fonction de vérification avec la clé, l’algorithme, l’émetteur et l’audience attendus.
FAQ
Faut-il le secret pour décoder un JWT ?
Non. L’en-tête et le payload sont seulement encodés en base64url. Le secret ou la clé publique sert à vérifier la signature, pas à lire le contenu.
Pourquoi mon JWT a-t-il cinq parties ?
C’est un jeton chiffré (JWE) : son contenu ne se lit qu’avec la clé de déchiffrement.
Comment savoir si un JWT a expiré ?
Comparez son claim exp, en secondes Unix, avec l’heure actuelle. Le décodeur JWT de ce site l’affiche en date et signale les jetons expirés.
Mis à jour : novembre 2026. Les fichiers sont traités dans votre navigateur et ne sont pas envoyés.