Json Web Token, c'est quoi et comment l'utiliser ?
Vendredi 28 Avril 2023 08:30

Json Web Token, c'est quoi et comment l'utiliser ?

Commençons par le commencement, un Json Web Token c’est ca:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrZXZpbnJvbGluLmJlIiwiZXhwIjoiMjAyMy0wNS0wN1QxMjoyMDoyMC4yMjhaIiwibWVzc2FnZSI6IkNvdWNvdSIsImlhdCI6IjIwMjMtMDUtMDZUMTI6MjA6MjAuMjI4WiJ9.oAaP1u7K5oX_fwlXFBxGMZT02M27EG0nqb-E7EEjpvU

Et bien que celà soit illisible, ce n’est pas pour autant crypté, il s’agit d’un simple encodage qui peut être inversé.

Mais en quoi est-ce sécurisé?

Vous l’aurez compris, les données présentes seront bien lisible pour celui qui obtiendra ce token. Il ne faut donc pas l'utiliser pour transférer des données sensibles!

La force de JWT est qu’il contient une signature permettant de vérifier l’authenticité du token.
Pour faire simple:

  • ServiceA génère le JWT via une clé secrète et l’envoi vers ServiceB
  • ServiceB reçoit le JWT et utilise la même clé secrète pour valider ou non le token

Celà permet donc de rajouter une couche de sécurité au cas où une faille permettrait à quelqu’un d’envoyer des données non souhaitée par le biais d’une API qui serait restée ouverte.

Lors de la vérification, le token va utiliser la clé secrète pour valider l’intégrité de son contenu.

Si quelqu’un venait à modifier le contenu du token, la validation échouerait.

Ça contient quoi?

Tout d’abord, comme son nom l’indique, c’est du json. Mais oui ça ne ressemble pas à du JSON car comme nous en avons parlé, il est encodé.

Les plus attentifs auront également remarqué que cette chaine de caractère se divise en trois parties via un point.

Header

L'en-tête ne contient que deux informations: le type de token et l'algorithme de signature.

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

Payload

Les données que vous souhaitez faire transiter sous la forme d’un tableau json.

Bien que non obligatoire, vous verrez souvent trois valeur supplémentaire:

  • "iss" Identifiant du service qui à généré le token
  • "exp" Date d’expiration
  • "iat" Date de création
{
  "iss": "kevinrolin.be",
  "exp": "2023-05-07T12:20:20.228Z",
  "message": "Coucou",
  "iat": "2023-05-06T12:20:20.228Z"
}

Signature

Je vous passe les détails car nous allons voir par la suite que des librairies existent et qu’on ne va donc pas trop se poser de question sur la partie signature.

Mais pour la faire simple, il s’agit d’une combinaison basée sur un encodage base64 du header + un encodage base64 du payload + la clé (encodée ou pas).

Cette combinaison est ensuite réencodée une nouvelle fois pour obtenir la string finale.

Exemple

Vous pouvez consulter les librairies sur le site officiel mais comme tout être humain, on aime quand les choses sont simples donc je vous propose quelques exemples ci-dessous.

Php

Mon choix c’est porté sur cette librairie: https://github.com/firebase/php-jwt

L’installation se fait via composer

composer require firebase/php-jwt

L’utilisation est ensuite assez simple: une fonction permet l’encodage en utilisant le payload sous forme d’array et le string de la clé privée permet de générer le token.

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$privateKey = 'kevinrolinbe';
$payload = [
    'message' => 'coucou'
];

$token = JWT::encode($payload, $privateKey, 'HS256');

Une seconde fonction permet de décoder le token

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$privateKey = 'kevinrolinbe';

$decoded = JWT::decode($token, new Key($privateKey, 'HS256'));

Node.JS

Pour node, je me suis dirigé vers la librairie officielle: https://github.com/auth0/node-jsonwebtoken

On passe par npm pour l’installation

npm install jsonwebtoken

L’initialisation se fait simplement:

const jwt = require('jsonwebtoken');

Il suffit ensuite de faire appel à la fonction sign avec le payload et la clé pour générer le token. Vous pouvez également spécifier un autre algorithme si nécessaire.

var privateKey = “kevinrolinbe”;
var payload = { message: 'coucou' };
var token = jwt.sign(payload, privateKey, { algorithm: 'RS256' });

Pour le décodage, c’est encore plus simple:

var privateKey = “kevinrolinbe”;
var decoded = jwt.verify(token, privateKey );
console.log(decoded.message);

Vérification

Si vous souhaitez vérifier votre token ou en générer un, vous pouvez utiliser le debugguer officiel à cette adresse: https://jwt.io

Personnellement, ça m'a permis de bien comprendre le fonctionnement.