🔬 Module 2 — Anatomie d'un JWT
Bonne lecture et bon apprentissage ! Junior TSAFACK – 12/09/2026 ⏱️ Temps de lecture estimé : 6 minutes
Un JWT ressemble toujours à ceci : trois blocs de texte séparés par des points.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTQyIiwibmFtZSI6Ikp1bmlvciBUU0FGQUNLIiwicm9sZSI6ImZvcm1hdGV1ciIsImlhdCI6MTc1NzY3ODQwMH0.nnywn_YNGOtGTbuj5A_qFUc_VtzUPUXJi5oqDB-Ne9g HEADER PAYLOAD SIGNATURE🧩 HEADER.PAYLOAD.SIGNATURE — retenez cet ordre, tout le reste du cours en découle.
Générons un vrai token pour l’observer
Section titled “Générons un vrai token pour l’observer”import base64import jsonimport jwt
SECRET = "un-secret-de-demonstration-ne-jamais-utiliser-en-production"
payload = { "sub": "user-42", "name": "Junior TSAFACK", "role": "formateur", "iat": 1757678400, # 2026-09-12T12:00:00Z (fixe pour un exemple reproductible)}
token = jwt.encode(payload, SECRET, algorithm="HS256")print("Token complet :")print(token)Sortie réellement obtenue :
Token complet :eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTQyIiwibmFtZSI6Ikp1bmlvciBUU0FGQUNLIiwicm9sZSI6ImZvcm1hdGV1ciIsImlhdCI6MTc1NzY3ODQwMH0.nnywn_YNGOtGTbuj5A_qFUc_VtzUPUXJi5oqDB-Ne9g1️⃣ Le HEADER : quel algorithme ?
Section titled “1️⃣ Le HEADER : quel algorithme ?”header_b64, payload_b64, signature_b64 = token.split(".")
def decode_part(b64_part: str) -> str: padded = b64_part + "=" * (-len(b64_part) % 4) return base64.urlsafe_b64decode(padded).decode()
print(decode_part(header_b64)){"alg":"HS256","typ":"JWT"}C’est juste du Base64URL (une variante de Base64 sans caractères qui posent problème dans une URL) — pas du chiffrement. alg annonce l’algorithme de signature utilisé (ici HS256, voir Module 4), typ confirme qu’il s’agit d’un JWT.
2️⃣ Le PAYLOAD : les données (« claims »)
Section titled “2️⃣ Le PAYLOAD : les données (« claims »)”print(json.dumps(json.loads(decode_part(payload_b64)), indent=2, ensure_ascii=False)){ "sub": "user-42", "name": "Junior TSAFACK", "role": "formateur", "iat": 1757678400}⚠️ N’importe qui peut décoder cette partie — nous venons de le faire avec trois lignes de Python, sans connaître le moindre secret. C’est pour ça que le Module 1 insistait : un JWT n’est jamais un coffre-fort, c’est une carte d’identité scellée.
Le payload est fait de claims (revendications). Certaines sont standardisées par la RFC 7519 et ont un sens particulier :
| Claim | Signification | Exemple |
|---|---|---|
sub (subject) |
L’identifiant de l’utilisateur/l’entité concernée | "user-42" |
iat (issued at) |
Horodatage Unix de la création du token | 1757678400 |
exp (expiration) |
Horodatage Unix après lequel le token est invalide | voir Module 4 |
iss (issuer) |
Qui a émis le token | "https://auth.monentreprise.com" |
aud (audience) |
Pour quel service ce token est destiné | "api-facturation" |
Rien n’empêche d’ajouter des claims « maison » (comme role ci-dessus) — c’est même l’usage le plus courant pour transporter des permissions.
3️⃣ La SIGNATURE : la seule partie qu’on ne peut pas lire
Section titled “3️⃣ La SIGNATURE : la seule partie qu’on ne peut pas lire”print(signature_b64)nnywn_YNGOtGTbuj5A_qFUc_VtzUPUXJi5oqDB-Ne9gContrairement aux deux premières parties, la signature n’est pas un encodage réversible de données : c’est le résultat d’une fonction cryptographique (HMAC-SHA256 pour HS256) appliquée à header_b64 + "." + payload_b64, avec un secret que seul le serveur connaît. On ne peut pas la « décoder » — on peut seulement la recalculer et comparer, ce qui est exactement ce que fait la vérification étudiée au Module 4.
🧠 À retenir
Section titled “🧠 À retenir”- Un JWT =
header.payload.signature, chacun encodé en Base64URL. - Header + Payload sont lisibles par tout le monde, signature ou pas.
- Seule la Signature garantit l’intégrité (« ça n’a pas été modifié ») — jamais la confidentialité.