Comprendre les tokens JWT en 3 minutes
Un JSON Web Token est un jeton signé permettant de contenir des informations indispensables à l'authentification d'un utilisateur... Mais comment cela fonctionne exactement ?
Article publié le 18/12/2023, dernière mise à jour le 18/12/2023
Les JSON Web Tokens (JWT) jouent un rôle crucial dans l’authentification sur Internet (via les sites web et les apps mobiles).
Dans cet article, on va explorer ensemble le concept des JWT, comprendre leur intérêt et leur fonctionnement pour garantir l'intégrité des données ( notamment la signature).
Utilisation
La première chose à comprendre, c’est que les tokens JWT sont utilisés dans des systèmes d’authentification (ou d’identification), mais ils ne suffisent pas à eux seuls pour gérer tout l’authentification !
Un token, c’est simplement un jeton, un identifiant qui va être échangé
Au casino, vous échangez un morceau de plastique (le jeton), contre une valeur financière (disons 50€), et bien dans une application, vous allez échanger votre jeton contre des données et des droits d’accès.
Mais contrairement aux jetons de casino, votre “token” contient des informations, vous concernant (l’utilisateur) et permet de vous identifier, et de prouver que c’est bien vous qui effectuez la demande !
Et l’avantage, c’est que vous ne perdez pas votre jeton en le partageant avec un serveur d’authentification, vous envoyez simplement une copie de ce jeton, qui pourra être lu par le serveur pour vous identifier !
Mais comment ça fonctionne exactement ?
Fonctionnement
La structure d'un token JWT
Voilà un token d’exemple :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiZXhwIjoxNjM4MzA2MzYyfQ.tzN8XdOlxOQo6fEOMY25Gbn6cNF5iYAOXA-oy89fJEg
Ca ressemble à n’importe quel identifiant unique chiffré me direz-vous !
Et pourtant, on est très loin du compte, car un token JWT n’est pas chiffré, il est signé, ce qui est très différent : ça signifie entre autre que son contenu est complètement public !
La preuve, si vous copiez-coller le token précédent sur le site jwt.io, vous obtiendrez le résultat suivant :
// header
{
"alg": "HS256",
"typ": "JWT"
}
// payload
{
"sub": "1234567890",
"name": "John Doe",
"exp": 1638306362
}
Observez le payload, vous verrez deux informations importantes, un nom et un id : “John Doe” et “1234567890”
Un JWT est composé de trois parties : l'en-tête (header), la charge utile (payload), et la signature (que nous verrons juste après).
L’en-tête et la charge utile sont simplement deux objets JSON, et pour former le token (la chaîne de caractère), il suffit de changer leur encodage en Base64, comme ceci :
const str = JSON.Stringify({
"alg": "HS256",
"typ": "JWT"
})
const header = btoa(str); //eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
La méthode btoa(…) permet de convertir en Base64, et il suffirait de faire la même chose avec le payload pour reconstituer notre token (sauf pour la signature)
Mais décortiquons maintenant le contenu de ce dernier :
En-tête (Header)
L'en-tête contient des métadonnées sur le type de token et l'algorithme de signature utilisé. Il ressemble à quelque chose comme ceci :
{
"alg": "HS256",
"typ": "JWT"
}
Charge Utile (Payload)
La charge utile transporte tout ce dont vous aurez besoin pour identifier un utilisateur, un exemple basique :
{
"sub": "1234567890",
"name": "John Doe"
"exp": 1638306362
}
C’est vous qui décidez ce dont vous avez besoin dans le payload !
Mais il y a quelques conventions qu’il est utile de respecter :
- “sub” représente l’identifiant utilisateur
- “exp” représente la date d’expiration du token (timestamp)
Signature
Mais la partie la plus importante d’un token, et qu’il nous reste à expliquer, c’est la signature !
C’est comme sur un chèque pour la banque, mais en plus sécurisé…
On pourrait penser que si il est possible de transformer un simple objet JSON, et de passer en Base64, il serait possible de se faire passer pour n’importe quel utilisateur !
Sauf qu’il vous manquera la signature… Et lorsque le serveur ouvrira le jeton falsifié, et verra que la signature ne concorde pas avec celle attendue, il rejettera le token immédiatement !
Pour créer cette signature, on a besoin de trois choses :
- l'en-tête du token
- la charge utile du token
- une clé secrète (à ne jamais partager)
- un algorithme spécifié dans l'en-tête (dans notre exemple, "HS256")
Et c’est en passant tout cela à la moulinette, que l’on va pouvoir signer notre token !
Et comme la clé secrète ne quitte jamais le serveur, alors il sera impossible pour quelqu’un d’autre d’emettre un token falsifié !
Autrement dit, si le serveur valide la signature, il peut utiliser les informations contenues dans le “payload” les yeux fermés, et identifier l’utilisateur !
On parle aussi de “lecture publique, écriture privée”
Conclusion
Un token JWT est un jeton d’identification contenant les informations nécessaires à un serveur pour authentifier l’utilisateur (souvent l’identifiant de ce dernier en base de données).
Le serveur peut se fier au token, si et seulement si la signature correspond à celle attendu, cela fait l’effet d’un sceau virtuel qui garantit que les données sont fiables et intègres.
Seul le serveur est habilité à créer un token JWT valide, car lui seul possède la clé privée !
Aucun commentaire pour l'instant