Sécurité · 4 min de lecture ·
Ce que contient un JWT, et pourquoi décoder n’est pas vérifier
Un JSON Web Token ressemble à une suite de caractères au hasard, mais tout le monde peut le lire. Ce que contiennent ses trois parties et l’erreur qui ouvre des failles de sécurité.

Un JWT (JSON Web Token) est la longue chaîne qui vous garde connecté à de nombreuses applications web et API. Il a l’air chiffré, mais la plupart du temps il ne l’est pas : quiconque possède le jeton peut lire ce qu’il contient.
Trois parties séparées par des points
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.3q2-7w…
└ header ──────────┘ └ payload ───────┘ └ signature
Le header indique comment le jeton est signé, par exemple HS256 ou RS256. Le payload contient les claims : qui est l’utilisateur (sub), quand le jeton a été émis (iat) et quand il expire (exp), plus tout ce que l’application ajoute, comme des rôles. Les deux sont du JSON encodé en base64url, un encodage et non un chiffrement.
C’est la signature qui compte
La troisième partie est une signature des deux premières, faite avec un secret ou une clé privée. Seul un serveur qui détient la bonne clé peut la vérifier. Si quelqu’un modifie un seul caractère du payload, par exemple le rôle de user à admin, la signature ne correspond plus.
Décoder n’est pas vérifier
Un jeton qui se décode proprement vous dit ce qu’il affirme, pas si c’est vrai. Votre backend doit vérifier la signature avec la clé, refuser les jetons dont l’exp est dépassé et n’accepter que les algorithmes attendus, jamais « none ». Les bibliothèques JWT le font pour vous ; sauter cette étape est une faille classique.
Règles pratiques
Ne mettez pas de secrets comme des mots de passe dans le payload, puisqu’il est lisible. Gardez des durées d’expiration courtes. Traitez un jeton comme un mot de passe tant qu’il est valide : quiconque le copie peut l’utiliser jusqu’à son expiration.
Où conserver un jeton dans le navigateur
Tout ce qui est stocké dans localStorage peut être lu par n’importe quel script de la page, donc une seule faille de cross-site scripting (XSS) peut faire fuiter le jeton. Un cookie HttpOnly n’est pas lisible par JavaScript, ce qui supprime ce risque ; associez-le aux attributs Secure et SameSite et à une protection contre la falsification de requêtes intersites (CSRF). Aucune option n’est parfaite, mais pour les jetons de session, les cookies HttpOnly sont le choix par défaut le plus sûr.
Expiration et jetons de rafraîchissement
Un JWT ne peut pas être « déconnecté » à lui seul : il reste valide jusqu’à son exp, sauf si le serveur tient une liste de révocation. C’est pourquoi les jetons d’accès vivent généralement quelques minutes, pas des jours. Un jeton de rafraîchissement à plus longue durée, conservé avec plus de soin et vérifié par le serveur, sert à obtenir un nouveau jeton d’accès quand l’ancien expire.
Les claims courants en un coup d’œil
iss émetteur qui a créé le jeton
sub sujet l’utilisateur ou le client concerné
aud audience quel service doit l’accepter
exp expiration heure Unix après laquelle il est invalide
nbf pas avant heure Unix avant laquelle il est invalide
iat émis le heure Unix de sa création
Les claims de temps sont des horodatages Unix en secondes. Le serveur doit vérifier aud en plus de exp : un jeton valide émis pour un service ne doit pas être accepté par un autre.
Lire un jeton
Le décodeur JWT de 4Dev découpe un jeton en ses parties et affiche le header et le payload en JSON lisible. Il se contente de décoder et ne vérifie pas la signature. Le jeton est envoyé au serveur de 4Dev pour être décodé, sans être journalisé ni conservé ; évitez tout de même de coller des jetons de production actifs, et révoquez tout jeton que vous pensez exposé.