Aller au contenu

JSON Web Token (JWT)

Qu'est-ce qu'un JSON Web Token (JWT) ?

Le JSON Web Token (JWT) est un standard ouvert (RFC 7519) qui définit une manière compacte et sécurisée de transmettre des informations entre deux parties sous forme d'objet JSON.

Ces informations peuvent être vérifiées et fiables car elles sont signées numériquement. Un JWT peut être signé à l'aide d'un secret (avec l'algorithme HMAC - Hash-based Message Authentication Code) ou d'une paire de clés publique/privée utilisant RSA ou ECDSA.

Pourquoi utiliser le JWT ? (Avantages)

L'utilisation des JWT présente plusieurs avantages majeurs, particulièrement dans le développement d'APIs modernes :

  1. Sans état (Stateless) : Contrairement aux sessions traditionnelles, le serveur n'a pas besoin de stocker d'informations de session en mémoire ou en base de données. Toutes les informations nécessaires à l'authentification sont contenues dans le jeton lui-même.
  2. Scalabilité : Comme le serveur est stateless, il est beaucoup plus facile de faire évoluer l'application horizontalement (plusieurs serveurs derrière un répartiteur de charge) car n'importe quel serveur peut valider le jeton sans consulter une base de données de sessions centrale.
  3. Performance : La validation d'un JWT est rapide car elle ne nécessite généralement pas de requête réseau vers une base de données ou un service tiers.
  4. Interopérabilité : Le format JSON est universel et supporté par presque tous les langages de programmation.
  5. Sécurité : Puisque le jeton est signé, le serveur peut détecter si les données ont été altérées par un tiers.

Comparaison : Clé API (Stateful) vs JWT (Stateless)

Caractéristique Clé API / Session (Stateful) JSON Web Token (Stateless)
Stockage serveur Nécessite une base de données ou un cache (Redis) pour valider la clé à chaque requête. Aucune donnée stockée sur le serveur. Le jeton contient tout.
Scalabilité Plus complexe (nécessite une base de données centrale ou une session collante). Facile (n'importe quel serveur peut valider le jeton avec la clé secrète).
Révocation Instantanée (il suffit de supprimer la clé en base de données). Difficile (le jeton reste valide jusqu'à son expiration, sauf si une "liste noire" est gérée).
Taille Très courte (simple identifiant). Plus longue (contient les données encodées et la signature).
Données (Payload) Aucune donnée dans la clé elle-même. Peut transporter des informations (ID utilisateur, rôles, etc.).
Utilisation type Accès permanent à une API, sessions web classiques. Authentification moderne, microservices, applications mobiles.

Access Token vs Refresh Token

Pour améliorer la sécurité, on utilise souvent deux jetons différents au lieu d'un seul.

1. Access Token (Jeton d'accès)

  • Rôle : Utilisé pour accéder aux ressources protégées (envoyé dans chaque requête).
  • Durée de vie : Très courte (ex: 15 minutes à 1 heure).
  • Sécurité : S'il est volé, l'attaquant ne peut l'utiliser que pendant une courte période.

2. Refresh Token (Jeton de rafraîchissement)

  • Rôle : Utilisé uniquement pour obtenir un nouvel Access Token quand l'ancien a expiré.
  • Durée de vie : Longue (ex: quelques jours à plusieurs mois).
  • Sécurité : Il est stocké de manière plus sécurisée (souvent dans un cookie HttpOnly côté client) et n'est envoyé qu'à la route de rafraîchissement.

Le flux classique :

  1. L'utilisateur se connecte et reçoit un Access Token et un Refresh Token.
  2. L'application utilise l'Access Token pour ses appels API.
  3. L'Access Token expire (erreur 401).
  4. L'application envoie le Refresh Token au serveur.
  5. Le serveur valide le Refresh Token et renvoie un nouvel Access Token.
  6. Si le Refresh Token est révoqué ou expiré, l'utilisateur doit se reconnecter manuellement.

Où stocker le JWT côté client ?

Le choix du lieu de stockage du jeton est crucial pour protéger votre application contre les attaques.

1. Local Storage + Header Authorization

  • Fonctionnement : Le jeton est stocké dans le localStorage du navigateur. Pour chaque requête, il est manuellement ajouté dans l'en-tête : Authorization: Bearer <token>.
  • Avantages : Très facile à implémenter dans les applications JavaScript (SPA).
  • Inconvénients (Danger) : Vulnérable aux attaques XSS (Cross-Site Scripting). Si un script malveillant s'exécute sur votre page, il peut lire tout le contenu du localStorage et voler le jeton.

2. Cookies (HttpOnly & Secure)

  • Fonctionnement : Le serveur envoie le jeton via un en-tête Set-Cookie. Le navigateur l'inclut automatiquement dans chaque requête vers le même domaine.
  • Avantages : En utilisant l'option HttpOnly, le JavaScript ne peut pas accéder au cookie, ce qui le protège contre le vol via XSS.
  • Inconvénients : Vulnérable aux attaques CSRF (Cross-Site Request Forgery). Il faut alors mettre en place des protections supplémentaires (attribut SameSite: Strict ou jetons anti-CSRF).

| Méthode | Accès via JavaScript | Protection XSS | Protection CSRF |

| :--- | :--- | :--- | :--- | | Local Storage | Oui | :x: Non | :white_check_mark: Oui | | Cookie (HttpOnly) | :x: Non | :white_check_mark: Oui | :warning: Nécessite SameSite/CSRF token |

Structure d'un JWT

Un JWT est composé de trois parties séparées par des points (.) :

xxxxx.yyyyy.zzzzz

1. L'en-tête (Header)

L'en-tête se compose généralement de deux parties : le type de jeton (JWT) et l'algorithme de signature utilisé (comme HS256 ou RS256).

{
  "alg": "HS256",
  "typ": "JWT"
}
Cet objet JSON est ensuite encodé en Base64Url.

2. La charge utile (Payload)

C'est ici que se trouvent les "claims" (revendications). Ce sont des déclarations sur une entité (généralement l'utilisateur) et des données supplémentaires.

  • Claims enregistrés (Reserved Claims) : Ce sont des clés prédéfinies recommandées pour garantir l'interopérabilité :
    • iss (Issuer) : Identifie qui a émis le jeton.
    • sub (Subject) : Identifie le sujet du jeton (ex: l'ID de l'utilisateur).
    • aud (Audience) : Identifie les destinataires auxquels le jeton est destiné.
    • exp (Expiration Time) : Date et heure d'expiration (format Unix Timestamp). Le jeton ne doit plus être accepté après cette date.
    • nbf (Not Before) : Date avant laquelle le jeton ne doit pas être accepté.
    • iat (Issued At) : Date à laquelle le jeton a été émis.
  • Claims publics/privés : Vos propres données personnalisées pour partager des informations entre services (ex: role, username, email, premium_user).

{
  "iss": "https://mon-api.com",
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022,
  "exp": 1516242622
}
Le Payload est également encodé en Base64Url.

3. La signature (Signature)

Pour créer la signature, vous devez prendre l'en-tête encodé, la charge utile encodée, un secret, et l'algorithme spécifié dans l'en-tête.

Par exemple, avec HS256 :

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)
La signature est utilisée pour vérifier que le message n'a pas été modifié en cours de route.

Algorithmes : HS256 vs RS256

Le choix de l'algorithme de signature est crucial pour la sécurité de votre architecture.

1. HS256 (Symétrique)

HMAC + SHA256. Une seule et même clé (le "secret") est utilisée pour signer et pour vérifier le jeton.

  • Avantages :
    • Très simple à implémenter.
    • Signature et vérification très rapides.
  • Inconvénients :
    • Partage du secret : Toutes les parties qui doivent vérifier le jeton doivent posséder le secret.
    • Risque de compromission : Si le secret est volé sur un serveur de vérification, l'attaquant peut forger de nouveaux jetons.
  • Usage : Idéal quand l'émetteur et le vérificateur sont le même service (application monolithique).

2. RS256 (Asymétrique)

RSA + SHA256. Utilise une paire de clés : une clé privée pour signer et une clé publique pour vérifier.

  • Avantages :
    • Plus sécurisé : Seul l'émetteur possède la clé privée.
    • Distribution publique : N'importe quel service peut posséder la clé publique pour vérifier le jeton sans aucun risque de pouvoir en créer un nouveau.
  • Inconvénients :
    • Plus complexe à mettre en œuvre (gestion des paires de clés).
    • Légèrement plus lent (calculs mathématiques asymétriques plus lourds).
  • Usage : Idéal pour les architectures microservices, les APIs publiques et les fournisseurs d'identité (Google, Microsoft, Auth0).

Exemple de signature RS256 :

RSASHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  private_key
)

Caractéristique HS256 RS256
Type de clé Clé secrète partagée Paire de clés (Privée/Publique)
Sécurité Risque si le secret est partagé Plus robuste, clé publique sans risque
Performance Plus rapide Légèrement plus lent (calcul asymétrique)
Cas d'usage Application interne, petit projet Microservices, SSO, APIs publiques

JWT et OpenID Connect (OIDC)

Le JWT est l'élément central du protocole OpenID Connect (OIDC), qui est une couche d'identité construite au-dessus d'OAuth 2.0.

Alors qu'OAuth 2.0 concerne l'autorisation (quelles ressources un utilisateur peut-il accéder ?), OIDC concerne l'authentification (qui est l'utilisateur ?).

Le jeton d'identité (ID Token)

Dans un flux OIDC, le serveur d'authentification (comme Google, GitHub ou Auth0) renvoie un ID Token. Ce jeton est obligatoirement un JWT.

Il permet au client (votre application) de :

  • Confirmer l'identité de l'utilisateur.
  • Obtenir des informations de profil de base (nom, email, photo) directement dans le jeton, sans appel API supplémentaire.

Pourquoi est-ce important ?

OIDC standardise la manière dont les JWT sont utilisés pour l'identité, ce qui permet le Single Sign-On (SSO) : un utilisateur peut se connecter à plusieurs applications différentes en utilisant le même compte centralisé.

Exemple concret avec un compte Google :

  1. Vous visitez un site tiers (ex: Canva ou Spotify).
  2. Au lieu de créer un nouveau compte, vous cliquez sur "Se connecter avec Google".
  3. Google vous authentifie et renvoie un ID Token (JWT) au site tiers.
  4. Le site tiers valide la signature du JWT (émise par Google) et extrait votre nom et email.
  5. Vous êtes connecté instantanément sans avoir jamais partagé votre mot de passe avec le site tiers.

Liens utiles

Médiagraphie