Les jetons JWT apparaissent dans presque chaque application web moderne — en-têtes d'authentification, flux de rafraîchissement, contrôle d'accès aux API. Ils sont également l'un des standards le plus mal utilisés dans le monde réel. Si vous les utilisez, il est essentiel de comprendre ce qui se trouve dans le jeton, ce que signifie décoder versus vérifier, et quelles raccourcis compromettent discrètement votre sécurité.
L'anatomie d'un JWT
Un JWT est composé de trois chaînes base64url encodées reliées par des points :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsImVtYWlsIjoiYWxpY2VAZXhhbXBsZS5jb20iLCJpYXQiOjE3MTI3NjQ4MDAsImV4cCI6MTcxMjg1MTIwMH0.4Xr8mNkZQWpH2TvL9uY3sKdJwFqBzEcAoMnRiVePxlU
- En-tête — l'algorithme et le type de jeton (
alg,typ) - Charge utile — les revendications (données que votre application a besoin)
- Signature — la signature HMAC ou RSA sur les deux premières parties
Décodé, le payload ressemble à ceci :
{
"sub": "user_123",
"email": "alice@example.com",
"iat": 1712764800,
"exp": 1712851200
}
Rien ici n'est chiffré. Quiconque détient le jeton peut lire ces valeurs. La signature prouve seulement que le jeton n'a pas été altéré après son émission — elle ne cache pas son contenu.
Décoder n'est pas vérifier
Cette distinction surprend davantage les développeurs qu'elle ne le devrait.
Décoder divise le jeton en parties séparées par des points et décode chaque section en base64url. Aucun secret n'est nécessaire — n'importe quel outil ou une ligne de commande peut le faire. Si vous souhaitez décoder un jeton JWT en ligne sans installer de logiciel, collez le jeton dans IO Tools Décrypteur JWT et obtenez immédiatement une analyse des en-têtes, du payload et de l'expiration.
Vérifier vérifie que la signature est valide en utilisant un secret (ou une clé publique pour les algorithmes asymétriques). Elle confirme également que le jeton n'est pas expiré et que les revendications correspondent à ce que votre application attend. Omettre la vérification et faire confiance à un jeton décodé est la cause d'attaques d'authentification.
Voici un extrait de code Node.js qui vérifie un JWT et gère les cas d'usage courants :
import jwt from 'jsonwebtoken';
const SECRET = process.env.JWT_SECRET;
function verifyToken(token) {
try {
const payload = jwt.verify(token, SECRET, {
algorithms: ['HS256'], // whitelist — never allow 'none'
audience: 'myapp', // validate aud claim
});
// jwt.verify throws if exp is in the past, but be explicit:
if (payload.exp < Math.floor(Date.now() / 1000)) {
throw new Error('Token expired');
}
return payload;
} catch (err) {
// Never silently swallow verification failures
throw new Error(`Invalid token: ${err.message}`);
}
}
Les revendications à valider
La spécification JWT définit des revendications standard que votre serveur doit activer, et non simplement lire :
| Revendication | Signification | Valider ? |
|---|---|---|
exp | Horodatage d'expiration | Toujours — les jetons périmés constituent une surface réelle d'attaque |
iat | Horodatage d'émission | Optionnel, utile pour les vérifications de durée maximale |
sub | Sujet (généralement l'identifiant de l'utilisateur) | Oui — confirmez qu'il correspond à l'utilisateur attendu |
aud | Public destinataire | Oui — empêche les jetons d'un service A d'être utilisés sur un service B |
La plupart des bibliothèques JWT les valident exp automatiquement — mais uniquement si vous les configurez. Lisez les documents de votre bibliothèque. Ne supposez pas qu'elle est activée par défaut.
Trois erreurs qui font brûler les développeurs
1. Le alg: none Attaque
La spécification JWT autorise une valeur d'algorithme de none, ce qui signifie qu'il n'y a pas de signature. Certaines bibliothèques — en particulier les anciennes — acceptent cela et omettent entièrement la vérification de la signature. Un attaquant retire la signature, modifie la valeur "alg": "none" dans l'en-tête et forge des revendications arbitraires. Le serveur les croit.
Solution : whitelist explicite des algorithmes lors de la vérification. Ne jamais accepter none. L'extrait de code ci-dessus montre cela avec algorithms: ['HS256'].
2. Ne pas valider l'expiration
Décoder un jeton et faire confiance au payload sans vérifier exp signifie qu'un jeton émis il y a des mois est toujours accepté. Si une session utilisateur a été révoquée ou qu'un attaquant a volé un ancien jeton, votre application ne le saura jamais.
Solution : considérez l'expiration comme obligatoire, pas optionnelle. Pour vérifier quand un jeton spécifique expire, IO Tools Vérificateur d'expiration JWT décode la exp revendication et vous indique exactement le temps restant — utile pour déboguer les flux de rafraîchissement sans écrire de code.
3. Stocker les JWT dans localStorage
localStorage est accessible par n'importe quel script JavaScript sur la page. Une seule vulnérabilité XSS permet à un attaquant d'extraire silencieusement le jeton d'authentification de l'utilisateur. Voici la comparaison des options de stockage :
| Stockage | Risque XSS | Risque CSRF | Accessible depuis JavaScript | Remarques |
|---|---|---|---|---|
| localStorage | Haut | Aucun | Oui | Éviter pour les jetons d'authentification |
| sessionStorage | Haut | Aucun | Oui | Mêmes risques que localStorage |
| cookie httpOnly | Aucun | Moyen | Non | Meilleur pour les jetons d'authentification ; associez-le à SameSite + un token CSRF |
| Stockage en mémoire (variable JS) | Faible | Aucun | Oui (même contexte) | Perdu lors du rafraîchissement ; adapté aux jetons à durée courte |
Les cookies httpOnly ne peuvent pas être lus par JavaScript, ce qui élimine entièrement le vecteur d'attaque XSS. Le compromis est l'exposition au CSRF, que vous gérez avec SameSite=Strict ou un token CSRF.
JWTs vs Sessions : Le vrai équilibre
Les JWT sont sans état — le serveur les valide sans consulter une base de données. Cela est utile dans les systèmes distribués où vous ne souhaitez pas que chaque service accède à un stockage partagé de sessions.
Mais l'absence d'état a un coût réel : vous ne pouvez pas révoquer un JWT avant son expiration. Si un utilisateur se déconnecte ou est compromis, le jeton reste valide jusqu'à exp. Des contournements (listes de blocage de jetons, durée courte + jetons de rafraîchissement) existent, mais ils ajoutent de la complexité et reproduisent souvent ce que fait déjà un stockage de session.
Utilisez les JWT lorsque : vous avez plusieurs services qui authentifient les demandes de manière indépendante, vous souhaitez intégrer directement les rôles et les permissions dans le jeton, ou que vos jetons sont à durée courte et que la latence de révocation est acceptable.
Utilisez les sessions lorsque : vous avez besoin de révocation immédiate (la déconnexion doit fonctionner réellement), vous construisez une application serveur-réndu, ou lorsque la simplicité l'emporte sur l'aspect de scalabilité sans état.
Inspecter un jeton en quelques secondes
Avez-vous besoin de voir ce qui se trouve dans un JWT maintenant ? Terminal :
echo "YOUR.JWT.HERE" | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool
Ou passez par le terminal — collez le jeton dans IO Tools Décrypteur JWT pour obtenir une analyse formatée de l'en-tête et du payload. Ces deux approches ne vérifient pas la signature ; elles décodent. Pour une lecture rapide de l'expiration sans écrire de code, le Vérificateur d'expiration JWT vous donne l'heure exacte et le temps restant.
Installez nos extensions
Ajoutez des outils IO à votre navigateur préféré pour un accès instantané et une recherche plus rapide
恵 Le Tableau de Bord Est Arrivé !
Tableau de Bord est une façon amusante de suivre vos jeux, toutes les données sont stockées dans votre navigateur. D'autres fonctionnalités arrivent bientôt !
Outils essentiels
Tout voir Nouveautés
Tout voirMise à jour: Notre dernier outil a été ajouté le 5 mai 2026
