Comprenez ce qu’est un JWT (JSON Web Token), les trois parties qui le composent, ses usages et les conseils de sécurité essentiels pour éviter les erreurs courantes liées aux jetons.

Un JWT (JSON Web Token) est une chaîne compacte et sûre pour les URL qui représente un ensemble d’informations (généralement sur un utilisateur ou une session) et qui peut être transmise entre systèmes. On le voit souvent sous la forme d’une longue valeur commençant par quelque chose comme eyJ..., envoyée dans un en‑tête HTTP tel que Authorization: Bearer <token>.
Les connexions traditionnelles reposent souvent sur des sessions serveur : après la connexion, le serveur stocke des données de session et donne au navigateur un cookie d’identifiant de session. Chaque requête inclut ce cookie et le serveur consulte la session.
Avec l’auth par jeton, le serveur peut éviter de garder l’état de session pour chaque requête utilisateur. Le client conserve un jeton (comme un JWT) et l’inclut dans les appels d’API. Cela est populaire pour les API parce que :
Nuance importante : « sans état » ne signifie pas « aucune vérification côté serveur ». De nombreux systèmes valident encore les jetons en fonction du statut de l’utilisateur, de la rotation des clés ou de mécanismes de révocation.
Les JWT contiennent souvent une preuve d’authentification (vous êtes connecté) et des indices d’autorisation basiques (rôles, permissions, scopes) — mais votre serveur doit toujours appliquer les règles d’autorisation.
On utilise souvent les JWT comme jetons d’accès dans :
Un JWT est une chaîne compacte composée de trois parties, chacune encodée en Base64URL et séparée par des points :
header.payload.signature
Exemple (raccourci) :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNzAwMDAwMDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c…
L’en‑tête décrit comment le jeton a été créé — principalement l’algorithme de signature (par ex. HS256, RS256/ES256) et le type de jeton.
Champs courants :
typ : souvent "JWT" (fréquemment ignoré en pratique)alg : l’algorithme de signature utilisékid : identifiant de clé pour aider le vérificateur à choisir la bonne clé lors d’une rotationNote de sécurité : ne faites pas aveuglément confiance à l’en‑tête. Imposer une allowlist des algorithmes réellement utilisés et n’acceptez pas alg: "none".
La charge utile contient des « claims » sur l’utilisateur et le contexte du jeton : pour qui il est, qui l’a émis et quand il expire.
Important : les JWT ne sont pas chiffrés par défaut. L’encodage Base64URL rend le jeton sûr pour les URL ; il ne cache pas les données.
C’est pourquoi vous devez éviter d’y placer des secrets (mots de passe, clés API) ou des données personnelles sensibles.
La signature est créée en signant l’en‑tête + la charge utile avec une clé :
La signature fournit l’intégrité : elle permet de vérifier que le jeton n’a pas été modifié et qu’il a été émis par un signataire de confiance. Elle ne fournit pas de confidentialité.
Parce qu’un JWT inclut l’en‑tête et la charge utile à chaque requête où il est envoyé, des jetons plus gros signifient plus de bande passante et de surcharge. Gardez les claims légers et préférez des identifiants plutôt que des données volumineuses.
Les claims se divisent généralement en deux catégories : enregistrés (noms standardisés) et personnalisés (champs propres à votre application).
iss (issuer) : qui a créé le jetonsub (subject) : à qui le jeton se rapporte (souvent un ID utilisateur)aud (audience) : pour qui le jeton est destiné (ex. une API spécifique)exp (expiration time) : quand le jeton ne doit plus être acceptéiat (issued at) : quand le jeton a été créénbf (not before) : le jeton ne doit pas être accepté avant cette heureIncluez seulement ce dont le service destinataire a réellement besoin pour prendre une décision d’autorisation.
Bons exemples :
user_id)Évitez les claims « de commodité » qui dupliquent beaucoup de données de profil. Ils alourdissent le jeton, se périment rapidement et augmentent l’impact en cas de fuite.
Comme la charge utile est lisible, n’y stockez pas :
Si vous avez besoin d’informations sensibles, stockez‑les côté serveur et mettez seulement une référence (par ex. un ID) dans le jeton — ou utilisez un format chiffré (JWE) si nécessaire.
Signer n’est pas chiffrer.
Quand un JWT est émis, le serveur signe l’en‑tête + la charge utile encodés. Quand le jeton est présenté plus tard, le serveur recalcule la signature et la compare. Si quelqu’un change une seule valeur (par ex. "role":"user" en "role":"admin"), la vérification échoue et le jeton est rejeté.
JWT est un format de jeton. OAuth 2.0 et OpenID Connect (OIDC) sont des protocoles qui décrivent comment les apps demandent, émettent et utilisent des jetons.
OAuth 2.0 concerne principalement l’autorisation : permettre à une application d’accéder à une API au nom d’un utilisateur sans partager le mot de passe.
Les access tokens sont typiquement de courte durée (minutes). Des durées courtes limitent les dégâts en cas de fuite.
OIDC ajoute l’authentification (qui est l’utilisateur) par‑dessus OAuth 2.0 et introduit un ID token, qui est généralement un JWT.
Règle clé : n’utilisez pas un ID token pour appeler une API.
Si vous voulez plus de contexte sur des flux pratiques, voir /blog/jwt-authentication-flow.
Un flux typique ressemble à ceci :
L’utilisateur se connecte (email/mot de passe, SSO, etc.). Si la connexion réussit, le serveur crée un JWT (souvent un access token) avec des claims essentiels comme le sujet et l’expiration.
Le serveur signe le jeton et le renvoie au client (application web, mobile ou un autre service).
Pour les endpoints protégés, le client inclut le JWT dans l’en‑tête Authorization :
Authorization: Bearer <JWT>
Avant de répondre, l’API vérifie généralement :
exp (non expiré)iss (émetteur attendu)aud (destiné à cette API)Si toutes les vérifications passent, l’API considère l’utilisateur comme authentifié et applique les règles d’autorisation (par ex. permissions au niveau des enregistrements).
Les horloges système dérivent parfois : beaucoup de systèmes autorisent un petit décalage d’horloge lors de la validation des claims temps comme exp (et parfois nbf). Gardez ce skew petit pour ne pas prolonger la validité des jetons plus que prévu.
Le choix de stockage change ce que les attaquants peuvent voler et à quel point ils peuvent rejouer un jeton.
Stockage en mémoire (souvent recommandé pour les SPA) : conserve l’access token dans l’état JS. Il est effacé au rafraîchissement et réduit le risque de “vol ultérieur”, mais une faille XSS peut toujours le lire pendant l’exécution. Associez‑le à des access tokens de courte durée et à un flux de rafraîchissement.
localStorage/sessionStorage : faciles mais risqués : toute vulnérabilité XSS peut exfiltrer les tokens. Si vous les utilisez, la prévention XSS est impérative (CSP, échappement, hygiène des dépendances) et gardez les tokens courts.
Cookies sécurisés (souvent le choix le plus sûr pour le web) : stockez les jetons dans un cookie HttpOnly pour que JavaScript ne puisse pas les lire — réduisant l’impact d’un vol via XSS. L’inconvénient est le risque CSRF, puisque les navigateurs joignent automatiquement les cookies.
Si vous utilisez des cookies, définissez :
HttpOnlySecure (HTTPS seulement)SameSite=Lax ou SameSite=Strict (certains flux inter‑sites peuvent nécessiter SameSite=None; Secure)Envisagez aussi des tokens CSRF pour les requêtes modifiantes.
Sur iOS/Android, stockez les tokens dans un stockage sécurisé (Keychain / Keystore). Évitez les fichiers en clair ou les préférences. Si votre modèle de menace inclut des appareils rootés/jailbreakés, assumez l’extraction possible et reposez‑vous sur des tokens de courte durée et des contrôles côté serveur.
Limitez ce qu’un jeton peut faire : utilisez des scopes/claims minimaux, gardez les access tokens de courte durée et évitez d’embarquer des données sensibles.
Les JWT sont pratiques, mais de nombreux incidents proviennent d’erreurs prévisibles. Traitez un JWT comme de l’argent liquide : celui qui l’obtient peut souvent le dépenser.
Si un jeton dure des jours ou des semaines, une fuite donne à un attaquant toute cette fenêtre.
Préférez des access tokens de courte durée (minutes) et renouvelez‑les via un mécanisme plus sûr. Pour un « se souvenir de moi », utilisez des refresh tokens et des contrôles côté serveur.
Une signature valide ne suffit pas. Vérifiez iss et aud, et validez les claims temporels comme exp et nbf.
Décoder n’est pas vérifier. Vérifiez toujours la signature côté serveur et appliquez les permissions côté serveur.
Évitez de mettre des JWT dans les paramètres de requête. Ils peuvent finir dans l’historique du navigateur, les logs serveur, les outils d’analytics et les en‑têtes Referer.
Utilisez Authorization: Bearer ... à la place.
Supposez que les clés et les jetons peuvent fuir. Faites tourner les clés de signature, utilisez kid pour supporter une rotation fluide et ayez une stratégie de révocation (expirations courtes + capacité à désactiver comptes/sessions). Pour des conseils de stockage, voir /blog/where-to-store-jwts-safely.
Les JWT sont utiles, mais ne sont pas automatiquement le meilleur choix. La vraie question est de savoir si vous bénéficiez d’un jeton autonome qui peut être vérifié sans interroger la base de données à chaque requête.
Pour les applications serveur‑rendu traditionnelles où l’invalidation est simple, les sessions côté serveur avec cookies HttpOnly sont souvent la valeur par défaut la plus simple et la plus sûre.
Choisissez JWT si vous avez besoin d’une vérification sans état entre services et pouvez garder les jetons de courte durée.
Évitez JWT si vous avez besoin d’une révocation immédiate, prévoyez de mettre des données sensibles dans le jeton, ou pouvez utiliser des cookies de session sans friction.
Vérifiez avec la clé correcte et l’algorithme attendu. Rejetez les signatures invalides — sans exception.
exp (expiration)Assurez‑vous que le jeton n’est pas expiré.
nbf (not before)Si présent, assurez‑vous que le jeton n’est pas utilisé trop tôt.
aud (audience)Confirmez que le jeton était destiné à votre API/service.
iss (issuer)Confirmez que le jeton vient de l’émetteur attendu.
Validez le format du jeton, imposez une taille maximale et rejetez les types de claims inattendus pour réduire les bugs liés aux cas limites.
HS256 (clé symétrique) : un secret partagé signe et vérifie.
RS256 / ES256 (clés asymétriques) : la clé privée signe ; la clé publique vérifie.
Règle générale : si plusieurs systèmes indépendants doivent vérifier les jetons (ou que vous ne faites pas entièrement confiance à chaque vérificateur), préférez RS256/ES256.
iss, aud, et un ID utilisateur seulement si la politique le permet).Les JWT sont‑ils chiffrés ?
Pas par défaut. La plupart des JWT sont signés, pas chiffrés : le contenu peut être lu par quiconque possède le jeton. Utilisez JWE ou évitez de mettre des données sensibles dans les JWT.
Puis‑je révoquer un JWT ?
Pas facilement si vous ne comptez que sur des access tokens autonomes. Approches courantes : access tokens de courte durée, listes de refus pour événements à haut risque, ou refresh tokens avec rotation.
Combien de temps doit durer exp ?
Aussi court que votre UX et votre architecture le permettent. Beaucoup d’APIs utilisent des minutes pour les access tokens, associées à des refresh tokens pour des sessions plus longues.
Si vous implémentez l’auth JWT dans une nouvelle API ou SPA, beaucoup de travail est répétitif : câbler le middleware, valider iss/aud/exp, définir les flags des cookies et éviter d’avoir du handling de jetons dans les logs.
Avec Koder.ai, vous pouvez générer rapidement une application web (React), des services backend (Go + PostgreSQL) ou une app mobile Flutter via un flux de travail basé sur le chat — itérer en mode planning, utiliser des snapshots et rollback pour affiner la sécurité, et exporter le code source quand vous êtes prêt. C’est un moyen pratique d’accélérer la construction de flux d’authentification JWT tout en gardant le contrôle sur la logique de vérification, la stratégie de rotation des clés et les paramètres de déploiement/hosting (y compris les domaines personnalisés).
Un JWT (JSON Web Token) est une chaîne compacte et sûre pour les URL qui transporte des « claims » (champs de données) et peut être vérifiée par un serveur. Il est couramment envoyé sur les requêtes d’API via :
Authorization: Bearer <token>L’idée clé : le serveur peut valider l’intégrité du jeton (via sa signature) sans avoir besoin d’un enregistrement de session par utilisateur pour chaque requête.
L’authentification par session stocke généralement l’état côté serveur (un enregistrement de session indexé par un cookie/ID de session). Avec l’authentification basée sur JWT, le client présente à chaque requête un jeton signé que l’API valide.
Les JWT sont populaires pour les API et les architectures multi‑services parce que la vérification peut se faire localement, réduisant le besoin d’un stockage partagé des sessions.
« Sans état » n’exclut pas toujours des vérifications côté serveur, comme des listes de révocation, le contrôle du statut utilisateur ou la rotation de clés.
Un JWT se compose de trois parties encodées en Base64URL et séparées par des points :
header.payload.signatureL’en‑tête décrit la façon dont il a été signé, la charge utile contient des claims (par ex. sub, exp, aud) et la signature permet au serveur de détecter toute modification.
Non. Les JWT standards sont généralement signés, pas chiffrés.
Si vous avez besoin de confidentialité, envisagez JWE (jetons chiffrés) ou conservez les données sensibles côté serveur et ne mettez qu’un identifiant dans le JWT.
La signature permet au serveur de vérifier que le jeton n’a pas été altéré et qu’il a été émis par quelqu’un possédant la clé de signature.
Elle ne garantit pas :
exp.Traitez le jeton comme un identifiant : s’il fuit, il peut souvent être réutilisé jusqu’à expiration.
alg indique l’algorithme utilisé (par ex. HS256 vs RS256). kid est un identifiant de clé qui aide à sélectionner la bonne clé lors de la rotation.
Règles de sécurité :
Commencez par les claims standards et gardez les claims personnalisés au minimum.
Claims enregistrés courants :
JWT est un format de jeton ; OAuth 2.0 et OpenID Connect sont des protocoles.
Correspondances typiques :
Pour les applications web :
Au minimum, vérifiez :
exp (non expiré)iss (émetteur attendu)aud (destiné à votre API)nbf (si présent)Garde‑fous pratiques :
alg.alg: "none".kid non fiable provoquer un comportement dangereux lors de la sélection de la clé.iss (issuer / émetteur)sub (subject / identifiant du sujet)aud (audience / destinataire prévu)exp (expiration)iat (issued at / émis à)nbf (not before)Évitez d’inclure des secrets ou des données personnelles sensibles dans la charge utile, car elles sont lisibles si le jeton est exposé.
Important : n’utilisez pas un ID token pour appeler une API simplement parce qu’il ressemble à un access token JWT.
Si vous utilisez des cookies, définissez :
HttpOnlySecure (HTTPS uniquement)SameSite=Lax ou SameSite=Strict (ou SameSite=None; Secure pour certains flux inter‑sites)Pensez aussi aux tokens CSRF pour les requêtes modifiantes.
Pour les applications mobiles : préférez le stockage sécurisé (Keychain / Keystore).