Un jeton JWT peut simplifier l’authentification d’une API, à condition de comprendre ce qu’il transporte, ce qu’il ne garantit pas et comment il doit être vérifié côté serveur. Dans cet article, je détaille sa structure, son cycle de vie, les bons réflexes de sécurité et les cas où une session classique reste plus raisonnable. L’objectif est simple: vous aider à choisir et à implémenter ce mécanisme sans faux sentiment de sécurité.
Les points à garder en tête avant d’adopter un JWT
- Un JWT transporte des claims JSON signés, pas une session serveur stockée de manière centralisée.
- Sa structure repose sur trois parties: en-tête, payload et signature.
- Le contenu du payload est lisible; il n’est pas chiffré par défaut.
- Dans une API, il faut toujours vérifier la signature, l’expiration, l’audience et l’émetteur.
- Le modèle est très pratique en architecture stateless, mais la révocation instantanée est plus délicate.
- Pour le web, la stratégie de stockage du token compte autant que l’algorithme de signature.

De quoi se compose un JWT
Je préfère partir de la structure, parce que c’est là que beaucoup de malentendus commencent. Un JWT est une chaîne découpée en trois blocs séparés par des points: header, payload et signature. Le header décrit l’algorithme utilisé, le payload contient les informations utiles, et la signature sert à prouver que le contenu n’a pas été modifié.
Techniquement, les blocs sont encodés en Base64url, ce qui les rend compacts et faciles à transporter dans un en-tête HTTP. En revanche, cet encodage ne protège rien à lui seul: n’importe qui peut décoder le payload si le token lui tombe sous la main. C’est pour cela qu’il faut distinguer clairement intégrité et confidentialité. La signature protège contre la falsification, pas contre la lecture.
Le cœur du JWT, ce sont les claims, c’est-à-dire les paires clé-valeur qui décrivent un sujet: identifiant utilisateur, rôle, date d’expiration, audience, émetteur, et parfois des données métiers plus spécifiques. J’évite d’y mettre des informations sensibles ou trop volatiles, car un token n’est pas un coffre-fort, c’est un conteneur signé.
| Claim | Rôle | Usage pratique |
|---|---|---|
sub |
Identifie le sujet | Je l’utilise souvent pour l’ID interne de l’utilisateur. |
exp |
Fixe l’expiration | Indispensable pour limiter la durée de vie du token. |
iss |
Indique l’émetteur | Utile pour rejeter un token signé par un autre système. |
aud |
Définit le destinataire | Très utile quand plusieurs API ou services coexistent. |
iat |
Horodate d’émission | Pratique pour analyser la fraîcheur d’un token. |
jti |
Identifiant unique | Je m’en sers quand j’ai besoin de traçabilité ou de révocation ciblée. |
Comment un JWT circule dans une API
Dans un flux classique, l’utilisateur s’authentifie une fois, le serveur émet un token signé, puis le client le renvoie à chaque requête protégée. C’est cette boucle qui permet d’éviter une vérification en base à chaque appel, à condition que la validation côté serveur soit faite sérieusement.
| Étape | Ce qui se passe | Point de vigilance |
|---|---|---|
| Connexion | L’utilisateur envoie ses identifiants. | Le mot de passe ne doit jamais finir dans le token. |
| Émission | L’API renvoie un access token signé. | La durée de vie doit rester courte. |
| Stockage | Le client conserve le token pour les appels suivants. | Le mode de stockage change fortement le niveau de risque. |
| Requête | Le client envoie le token dans l’en-tête Authorization: Bearer .... |
C’est la méthode la plus propre pour une API HTTP. |
| Validation | Le serveur vérifie signature, expiration et claims attendus. | Une signature valide ne suffit pas si l’audience est mauvaise. |
Je vois souvent une confusion entre “le serveur n’a rien à faire” et “le serveur n’a rien à stocker”. Ce n’est pas la même chose. Un backend stateless n’est pas un backend aveugle: il doit toujours vérifier la signature, l’algorithme attendu, l’expiration, l’émetteur et l’audience. Si ces contrôles échouent, la requête doit être rejetée sans discussion.
Pour une application web, le stockage mérite une vraie décision d’architecture. En pratique, je privilégie souvent les cookies httpOnly quand le contexte le permet, parce qu’ils réduisent l’exposition au JavaScript côté navigateur. En contrepartie, il faut penser au CSRF et adapter la protection. Si l’application repose sur une SPA ou un flux mobile, d’autres compromis peuvent être plus pertinents, mais ils doivent être assumés, pas subis.
La logique d’ensemble est donc simple: le JWT transporte l’identité et quelques attributs, le serveur vérifie, puis il applique ses règles d’autorisation. C’est précisément cette séparation qui explique pourquoi le sujet vaut d’être utilisé avec discernement.
Quand je le recommande vraiment
Je recommande ce modèle quand l’objectif principal est de simplifier l’échange d’informations vérifiables entre plusieurs services ou clients. Il devient particulièrement intéressant dans trois cas: les API consommées par différents frontends, les architectures de microservices et les applications mobiles qui ont besoin d’un format compact et standardisé.
- API stateless - utile quand vous voulez scaler horizontalement sans synchroniser des sessions serveur.
- Microservices - pratique si plusieurs services doivent vérifier l’identité sans interroger une base centrale à chaque appel.
- Clients multiples - pertinent si une même logique d’authentification doit servir un site web, une app mobile et une API publique.
- Claims contrôlés - intéressant lorsque les informations transportées sont limitées, stables et non sensibles.
À l’inverse, je deviens prudent dès qu’on me demande une révocation immédiate, une déconnexion instantanée sur tous les appareils ou une invalidation fréquente des droits. Dans ces cas, un token autoporté peut devenir gênant. Le problème n’est pas le JWT en soi; le problème, c’est l’écart entre ses forces et le besoin réel du produit.
Autrement dit, je le choisis pour sa souplesse et sa compatibilité, pas par réflexe. Si le besoin principal est la gestion fine d’une session centrale, le serveur d’état peut rester le meilleur outil.
Les règles de sécurité que je ne saute jamais
Sur le terrain, la plupart des incidents ne viennent pas du standard lui-même, mais d’une implémentation trop optimiste. L’OWASP insiste notamment sur trois points que je retrouve souvent dans les revues de code: la signature doit être validée, l’algorithme attendu doit être fixé, et le payload ne doit pas exposer d’informations sensibles.
- Vérifier la signature à chaque requête - un token non vérifié n’a aucune valeur.
- Fixer l’algorithme côté serveur - ne jamais faire confiance à ce que le token annonce lui-même.
- Limiter la durée de vie - dans beaucoup d’équipes, un access token vit entre 5 et 15 minutes.
- Prévoir un refresh token - si l’expérience utilisateur doit rester fluide, il faut un mécanisme de renouvellement.
- Ne rien mettre de sensible dans le payload - email, rôle ou ID, oui; mot de passe, secret métier ou données confidentielles, non.
- Transporter le token en HTTPS uniquement - sans chiffrement de la couche transport, tout le reste devient fragile.
- Penser à la révocation - rotation de clés, liste noire ciblée ou expiration courte selon le niveau d’exigence.
Il y a aussi une nuance que je trouve importante: un token plus long n’est pas un token “plus confortable”, c’est souvent un token plus risqué. Plus la durée de vie s’allonge, plus vous reportez le coût d’une compromission éventuelle. C’est pour cela que je préfère des access tokens courts et des refresh tokens mieux contrôlés, plutôt qu’un seul jeton à la durée généreuse.
Enfin, gardez en tête que la sécurité d’un JWT ne se résume pas à la cryptographie. Le stockage côté client, la rotation des clés, la politique de logout et la gestion du vol de token comptent tout autant. C’est rarement la partie la plus glamour du sujet, mais c’est celle qui fait la différence en production.
JWT ou session serveur selon le cas d’usage
Je ne présente pas ces deux approches comme des ennemies. Elles résolvent le même besoin général, mais avec des priorités différentes. Si votre équipe cherche la simplicité opérationnelle et une révocation immédiate, la session serveur reste souvent la voie la plus nette. Si vous cherchez la vérification autonome et la compatibilité entre plusieurs services, le JWT prend l’avantage.
| Critère | JWT | Session serveur |
|---|---|---|
| État côté serveur | Faible ou nul pour la validation de base | État conservé dans une session centralisée |
| Scalabilité horizontale | Très bonne, surtout pour des API distribuées | Bonne, mais dépend d’un stockage partagé |
| Révocation immédiate | Plus complexe | Plus simple |
| Volume transporté | Plus élevé, car le token contient des claims | Faible, la session garde un identifiant court |
| Lisibilité côté client | Le payload est décodable | Opaque pour le client |
| Cas typiques | API, mobile, microservices, SSO | Applications web classiques, administration simple, logout immédiat |
Ce tableau ne sert pas à sacrer un vainqueur universel. Il montre simplement que le bon choix dépend de la contrainte dominante. J’ai vu des projets choisir JWT par habitude alors qu’une session aurait été plus sûre et plus simple à opérer. J’ai vu aussi l’inverse: des équipes empiler des sessions là où un token signé aurait réduit la friction entre services. Le bon réflexe, c’est de partir du besoin de révocation, du nombre de clients et du niveau de distribution du système.
Si vous hésitez encore, une règle pratique me semble utile: plus votre auth est distribuée, plus le JWT devient intéressant; plus votre contrôle doit être immédiat, plus la session garde du sens.
Un exemple concret pour une API d’authentification
Prenons un cas simple: une API de back-office pour une équipe éditoriale. L’utilisateur se connecte, le serveur émet un access token de courte durée, puis le client l’envoie dans chaque appel vers les routes protégées. Le payload peut contenir l’identifiant du compte, un rôle global et quelques métadonnées de validation.
{
"sub": "user_1842",
"role": "editor",
"iss": "api.exemple.fr",
"aud": "backoffice-web",
"iat": 1760000000,
"exp": 1760000900,
"jti": "2f9b5f2a-7e1b-4f1b-bd8c-7c0edb1c9f3e"
}
Dans cet exemple, je garde le token volontairement sobre. L’ID utilisateur sert à relier la requête à un compte connu, le rôle facilite une autorisation large, et les champs temporels limitent la fenêtre d’abus. Je n’y mets pas la liste complète des permissions fines, parce qu’elle change plus vite que le token lui-même. Si un droit doit être révoqué immédiatement, je le contrôle plutôt côté API ou dans un moteur d’autorisation dédié.
Le schéma le plus robuste ressemble souvent à ceci: access token court pour les appels courants, refresh token mieux protégé pour renouveler l’accès, et vérification stricte des claims à chaque échange. Cette combinaison apporte un bon équilibre entre confort utilisateur et maîtrise du risque. Elle n’élimine pas tous les problèmes, mais elle évite les excès les plus fréquents.
J’ajoute un dernier point qui surprend encore certaines équipes: si les droits d’un utilisateur changent souvent, un token long devient vite incohérent. Dans ce cas, je préfère une durée courte et un renouvellement contrôlé plutôt qu’un token “confortable” qui garde des permissions obsolètes trop longtemps.
Ce qu’il faut garder en tête pour une API propre et durable
Si je résume la logique métier sans la simplifier à l’excès, je dirais ceci: le JWT est très bon pour transporter des informations signées, beaucoup moins pour remplacer à lui seul toute stratégie d’authentification. Il fonctionne bien quand les claims sont limités, la durée de vie courte et la validation irréprochable.
- Je l’utilise pour des APIs distribuées, pas pour contourner les règles de sécurité.
- Je vérifie toujours les claims critiques au serveur, même si le token semble correct.
- Je garde le payload minimal et je protège le transport, le stockage et la révocation.
- Je choisis une alternative plus simple dès que la révocation instantanée devient un besoin majeur.
Dans la pratique, ce sont rarement les spécifications qui posent problème. Ce sont les compromis mal assumés: token trop long, payload trop bavard, validation trop permissive ou stockage trop exposé. Si vous gardez ces quatre risques en tête, vous pourrez utiliser les JWT avec nettement plus de confiance dans une architecture backend et API.