Comment décoder un JWT pour lire son en-tête et son payload ?

Un JWT (*JSON Web Token*) est généralement composé de trois segments séparés par des points : un en-tête, un payload et une signature. Les deux premiers sont encodés en Base64URL et peuvent être lus sans la clé de signature. Voici comment décoder un JWT localement, tout en comprenant les limites de cette opération.
✓ Vérifié le 11 octobre 2026 · 4 min de lecture

Comprendre la structure d’un JWT

Un JWT signé au format compact JWS suit généralement cette structure :

en-tête.payload.signature

Chaque segment a un rôle précis :

  • En-tête (header) : indique notamment le type de jeton et l’algorithme utilisé, par exemple JWT et HS256.
  • Payload : contient des claims, c’est-à-dire des informations associées au jeton.
  • Signature : sert à vérifier l’intégrité et l’authenticité du contenu selon le mécanisme utilisé.

Les deux premiers segments sont encodés en Base64URL. Ils peuvent donc être décodés sans disposer de la clé de signature. En revanche, décoder un JWT ne signifie pas le valider.

Décoder un JWT en JavaScript

Dans un navigateur, il faut convertir le Base64URL en Base64, rétablir le remplissage éventuel, puis interpréter les octets comme du JSON UTF-8.

function decodeBase64UrlJson(value) {
  const base64 = value
    .replace(/-/g, "+")
    .replace(/_/g, "/");

  const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
  const binary = atob(padded);
  const bytes = Uint8Array.from(binary, char => char.charCodeAt(0));
  const json = new TextDecoder("utf-8").decode(bytes);

  return JSON.parse(json);
}

function decodeJwt(token) {
  const parts = token.split(".");

  if (parts.length !== 3) {
    throw new Error("Le jeton ne contient pas trois segments.");
  }

  return {
    header: decodeBase64UrlJson(parts[0]),
    payload: decodeBase64UrlJson(parts[1]),
    signature: parts[2]
  };
}

const token = "VOTRE_JWT_ICI";
const decoded = decodeJwt(token);

console.log("En-tête :", decoded.header);
console.log("Payload :", decoded.payload);

Comment fonctionne ce code ?

  1. split(".") sépare les trois segments du JWT.
  2. Les caractères Base64URL - et _ sont convertis en caractères Base64 classiques.
  3. Le padding manquant, représenté par =, est ajouté.
  4. Le contenu est décodé en octets, puis converti en texte UTF-8.
  5. Le texte est enfin analysé comme du JSON.

Décoder un JWT en Python

En Python, le module standard base64 permet de décoder les segments Base64URL.

import base64
import json


def decode_base64url_json(value):
    padding = "=" * (-len(value) % 4)
    decoded = base64.urlsafe_b64decode(value + padding)
    return json.loads(decoded.decode("utf-8"))


def decode_jwt(token):
    parts = token.split(".")

    if len(parts) != 3:
        raise ValueError("Le jeton ne contient pas trois segments.")

    return {
        "header": decode_base64url_json(parts[0]),
        "payload": decode_base64url_json(parts[1]),
        "signature": parts[2],
    }


token = "VOTRE_JWT_ICI"
decoded = decode_jwt(token)

print("En-tête :", decoded["header"])
print("Payload :", decoded["payload"])

À quoi ressemblent l’en-tête et le payload ?

Après décodage, l’en-tête peut ressembler à ceci :

{
  "alg": "HS256",
  "typ": "JWT"
}

Le payload peut contenir des claims comme :

{
  "sub": "1234567890",
  "name": "Jane Doe",
  "iss": "https://exemple.test",
  "aud": "mon-api",
  "iat": 1710000000,
  "exp": 1710003600
}

iss identifie généralement l’émetteur, sub le sujet, aud l’audience, iat la date d’émission et exp la date d’expiration. Ces claims ne sont pas obligatoires dans tous les jetons et leur interprétation dépend de l’application.

Décodage et validation : deux opérations différentes

Le décodage permet uniquement de lire le contenu présenté par le jeton. Il ne permet pas de confirmer que :

  • le JWT a été émis par un serveur de confiance ;
  • son contenu n’a pas été modifié ;
  • sa signature est correcte ;
  • il n’est pas expiré ou utilisé avant sa date de validité ;
  • l’utilisateur dispose réellement de l’autorisation demandée.

Pour accepter un JWT, l’application doit utiliser une bibliothèque adaptée et vérifier notamment la signature, les algorithmes autorisés, l’émetteur (iss), l’audience (aud) et les dates comme exp ou nbf. La liste des algorithmes acceptés doit être définie explicitement.

Décoder un JWT avec un outil en ligne

jwt.io propose un débogueur capable d’afficher l’en-tête et le payload d’un JWT. Cet outil peut aussi aider à vérifier une signature lorsque la clé et les paramètres nécessaires sont disponibles.

Évitez toutefois de copier un jeton réel dans un service tiers sans connaître ses conditions de traitement. Un décodage local, dans le navigateur ou dans un script, limite l’exposition du token.

Précautions à prendre

Un JWT signé n’est pas forcément chiffré

Un JWT signé peut être lu par toute personne qui possède le token. Ne placez donc pas de mot de passe, de clé privée ou d’information confidentielle dans son payload, sauf si un mécanisme de chiffrement approprié est utilisé.

Le cas d’un JWE chiffré

Un jeton JWE compact chiffré comporte généralement cinq segments :

protected-header.encrypted-key.iv.ciphertext.authentication-tag

Son en-tête protégé peut être décodé, mais son contenu chiffré ne peut pas être lu par un simple décodage Base64URL. Une clé et une procédure de déchiffrement adaptées sont nécessaires.

La méthode en résumé

  1. Récupérez le JWT.
  2. Séparez-le avec le caractère ..
  3. Décodez le premier segment en Base64URL puis en JSON pour lire l’en-tête.
  4. Décodez le deuxième segment de la même façon pour lire le payload.
  5. Considérez le résultat comme une information lisible, pas comme une preuve de validité.
  6. Effectuez séparément la vérification cryptographique et les contrôles métier.

À retenir

  • Un JWT signé classique contient trois segments : en-tête, payload et signature.
  • Les deux premiers segments sont lisibles après décodage Base64URL, sans clé de signature.
  • Décoder un JWT ne vérifie ni sa signature, ni son émetteur, ni son expiration.
  • Un JWT signé n’est pas nécessairement chiffré : son payload ne doit pas contenir de secrets.
  • Un JWE chiffré ne peut pas être lu avec un simple décodage Base64URL.

Questions fréquentes

Peut-on décoder un JWT sans sa clé secrète ?
Oui. Pour un JWT signé classique, l’en-tête et le payload sont encodés en Base64URL et peuvent être lus sans clé. La clé reste nécessaire pour vérifier la signature, selon l’algorithme utilisé.
Décoder un JWT permet-il de savoir s’il est valide ?
Non. Le décodage permet seulement de lire son contenu. La validation doit aussi vérifier la signature, l’algorithme autorisé, l’émetteur, l’audience, l’expiration et les règles de l’application.
Le payload d’un JWT est-il secret ?
Non, pas lorsqu’il s’agit d’un JWT signé mais non chiffré. Toute personne qui possède le token peut généralement décoder son payload. N’y placez pas de mots de passe ni de clés privées.
Pourquoi un JWT contient-il parfois cinq segments ?
Un JWE compact chiffré comporte cinq segments. Son contenu est chiffré et nécessite une clé ainsi qu’une procédure de déchiffrement ; un simple décodage Base64URL ne suffit pas.

Sources & vérification

Les informations de ce guide s’appuient sur les sources ci-dessous. Elles sont conservées pour faciliter les vérifications et les mises à jour.