JWT « Invalid Signature » et autres erreurs de token courantes, expliquées

Ce qui provoque réellement une erreur de signature invalide sur un JWT, en quoi elle diffère d'un token expiré, et comment lire le header et le payload d'un token pour trouver le vrai problème en quelques secondes.

Un JWT est constitué de trois parties encodées en Base64URL reliées par des points — header.payload.signature. Le header et le payload ne sont que du JSON encodé et peuvent être lus par n'importe qui sans aucun secret ; la signature est la seule partie qui prouve réellement que le token a été émis par celui qui détient la clé secrète, et c'est de là que vient presque chaque erreur JWT déroutante.

« Invalid signature » ne signifie presque jamais que le token est malformé

Cette erreur signifie que le serveur a recalculé la signature avec sa propre clé secrète et obtenu un résultat différent de celui joint au token. La structure et le JSON du token sont généralement parfaitement valides — l'écart vient presque toujours de l'une de ces trois choses : la clé secrète utilisée pour vérifier ne correspond pas à celle utilisée pour signer (fréquent juste après une rotation de clé ou entre environnements), l'algorithme du header (alg) ne correspond pas à ce que le serveur attend, ou le payload a été altéré ou réencodé après la signature, même par quelque chose d'aussi minime qu'une réserialisation du JSON avec un ordre de clés ou des espaces différents.

« Token expired » est un problème totalement différent, et bien plus simple

Celui-ci n'a rien à voir avec la signature — il signifie que la signature a été vérifiée correctement, mais que le claim 'exp' du payload est un horodatage dans le passé. Le token fonctionne exactement comme prévu. La solution consiste simplement à obtenir un nouveau token (généralement via un flux de refresh token), pas à toucher à la logique de signature.

« alg: none » et pourquoi il doit toujours être rejeté

La spécification JWT autorise techniquement une valeur 'alg' égale à 'none', ce qui signifie que le token n'a aucune signature. Un serveur qui fait confiance à l'algorithme indiqué dans le token lui-même — plutôt que de n'accepter que le ou les algorithmes qu'il attend explicitement — peut être trompé pour accepter un token totalement non signé, fabriqué par un attaquant. Validez toujours côté serveur contre une liste explicite d'algorithmes autorisés, ne faites jamais confiance au champ 'alg' du token.

Comment vraiment le déboguer en moins d'une minute

Collez le token dans un décodeur et vérifiez trois choses dans l'ordre : le 'alg' du header correspond-il à ce avec quoi votre serveur signe, le claim 'exp' est-il dans le futur, et le payload contient-il les claims (comme 'sub' ou un rôle personnalisé) que votre code attend de lire. Neuf fois sur dix, le bug se trouve dans l'un de ces trois champs, pas dans la cryptographie elle-même.

Notre décodeur JWT sépare instantanément le header, le payload et la signature, et signale automatiquement un token expiré — comme tout s'exécute dans votre navigateur, il est sûr de coller un vrai token actif en déboguant un problème en production.

→ Décodeur JWT