aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Développement Web

JWT, c'est quoi ? L'authentification par token expliquée

Quand on construit une API, on finit toujours par se poser la même question : une fois l'utilisateur connecté, comment le reconnaître à chaque requête suivante ? La réponse à la question qu'est-ce qu'un JWT se trouve exactement ici. Un JWT (JSON Web Token) est comme une carte d'identité autonome que le serveur crée, signe et remet au client. Le client renvoie cette carte à chaque requête, et le serveur peut vérifier la signature et dire « oui, c'est bien un token que j'ai émis » — sans jamais interroger la base de données.

Qu'est-ce qu'un JWT et pourquoi l'utiliser ?

Dans la gestion de session classique, le serveur garde un enregistrement de session pour chaque utilisateur connecté et donne au client un identifiant de session. Cela fonctionne, mais le serveur doit mémoriser un état. Si vous avez plusieurs serveurs, ils doivent tous partager le même magasin de sessions.

Le JWT inverse cette logique. Le token contient lui-même les informations sur l'utilisateur (qui il est, son rôle, une date d'expiration) et il est signé avec la clé secrète du serveur. Le serveur n'a rien à mémoriser ; il lui suffit de vérifier la signature du token reçu. C'est pourquoi on parle d'authentification stateless (sans état), et c'est exactement ce qui la rend si courante dans les microservices, les applications mobiles et les API.

Les trois parties d'un token

Un JWT se compose de trois parties séparées par des points : header.payload.signature. Chaque partie est encodée en Base64Url (encodée, et non chiffrée — une distinction importante).

  • Header (en-tête) : indique le type du token et l'algorithme de signature utilisé. Exemple : {"alg":"HS256","typ":"JWT"}.
  • Payload (charge utile) : porte les « claims » (revendications) — par exemple l'id de l'utilisateur (sub), la date d'expiration (exp), la date de création (iat) et les champs que vous ajoutez vous-même (comme un rôle).
  • Signature : le header et le payload signés avec la clé secrète. C'est cette partie qui garantit que le token n'a pas été altéré.

Un vrai token ressemble à ceci :

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3MTk1MDAwMDB9
.s5_3kF9vQk2...signature

Un point essentiel : le payload n'est pas chiffré. N'importe qui peut décoder et lire du Base64Url. Donc ne mettez jamais de secrets comme des mots de passe ou des numéros de carte dans un token. Un token porte une « identité », pas des secrets.

Comment fonctionne la signature ?

La signature est le cœur de tout le modèle de sécurité du JWT. Avec l'algorithme HS256 (HMAC + SHA-256), elle se calcule ainsi :

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  cleSecrete
)

Quand le serveur vérifie un token, il répète exactement la même opération : il resigne le header et le payload reçus avec sa propre clé secrète et compare le résultat avec la signature du token. Si quelqu'un tente de changer le rôle dans le payload de user à admin, la signature ne correspondra plus, car l'attaquant n'a pas la clé secrète. Voilà pourquoi le token est « inviolable ».

Il existe deux approches de signature :

  • HS256 (symétrique) : une seule clé secrète signe et vérifie. Simple et rapide, mais quiconque peut vérifier peut aussi émettre des tokens.
  • RS256 (asymétrique) : signe avec une clé privée, vérifie avec une clé publique. Idéal quand plusieurs services doivent vérifier les tokens mais ne doivent pas pouvoir les émettre.

En pratique : émettre et vérifier un token

En Node.js, avec la bibliothèque jsonwebtoken, le flux est très lisible :

const jwt = require('jsonwebtoken');

// Émettre un token après une connexion réussie
const token = jwt.sign(
  { sub: user.id, role: user.role },
  process.env.JWT_SECRET,
  { expiresIn: '15m' }
);

// Le vérifier aux requêtes suivantes
try {
  const payload = jwt.verify(token, process.env.JWT_SECRET);
  // identifier l'utilisateur via payload.sub
} catch (err) {
  // signature invalide ou expirée
}

Le client envoie généralement ce token dans l'en-tête Authorization: Bearer <token>. Un middleware côté serveur lit cet en-tête à chaque requête, le vérifie et attache l'utilisateur à la requête.

Le pattern du refresh token

Il y a ici une tension : on veut un token à courte durée de vie (pour limiter les dégâts s'il est volé), mais forcer l'utilisateur à se reconnecter toutes les 15 minutes est une mauvaise expérience. La solution consiste à utiliser deux tokens :

  • Access token : courte durée de vie (par exemple 15 minutes). Envoyé à chaque requête API.
  • Refresh token : longue durée de vie (par exemple 7 jours). Utilisé uniquement pour obtenir un nouvel access token.

Quand l'access token expire, le client envoie le refresh token au serveur et reçoit en retour un access token frais — l'utilisateur ne remarque rien. Les détails de sécurité importants :

  • Il faut stocker le refresh token côté serveur (ou tenir une liste de révocation) pour que la « déconnexion » puisse réellement l'invalider. Un access token pur est sans état, il reste donc valide jusqu'à son expiration.
  • Garder le refresh token dans un cookie HttpOnly dans le navigateur empêche le JavaScript de le lire et de le voler via une attaque XSS.
  • Émettre un nouveau refresh token à chaque usage et invalider l'ancien (rotation) réduit fortement le risque de vol.

Erreurs fréquentes

  • Mettre des secrets dans le payload : le payload est public, ne l'oubliez pas.
  • Ne pas définir d'expiration (exp) : un token sans expiration reste valide pour toujours une fois volé.
  • Accepter alg: none : configurez votre bibliothèque pour qu'elle indique explicitement quels algorithmes elle accepte.
  • Coder la clé secrète en dur : la clé doit être dans une variable d'environnement (.env), pas dans le dépôt.

Questions fréquentes

Un JWT est-il chiffré ?

Non. Par défaut, un JWT est signé, pas chiffré. Son contenu est lisible mais ne peut pas être modifié. Si vous voulez aussi masquer le contenu, JWE (JSON Web Encryption) est un standard à part — mais dans la plupart des cas, le bon réflexe est simplement de ne jamais mettre de données sensibles dans le token.

Où dois-je stocker le token ?

Il n'y a pas de réponse parfaite unique. localStorage est facile mais exposé aux attaques XSS. Un cookie HttpOnly est protégé contre le XSS mais nécessite une protection CSRF. Sur mobile, on préfère un stockage sécurisé (Keychain/Keystore).

Puis-je révoquer un JWT individuel ?

Un JWT pur étant sans état, il ne peut pas être révoqué directement ; il reste valide jusqu'à son expiration. Si la révocation est nécessaire, on utilise un access token à courte durée de vie plus un refresh token côté serveur (liste de révocation).

Bien mettre en place l'authentification est le fondement de la sécurité d'un projet. Si vous avez besoin d'aide pour mettre en place un JWT, un flux de refresh token ou une architecture d'API sécurisée en général, contactez-moi — posons ensemble des bases solides.

Bu kategorideki tüm yazılar →

Devamı için