Formation PUB900 : Développer une application pour iPhone avec SwiftUI, H-2024 Consommer un service Web avec SwiftUI (technique traditionnelle)

49.3 Bearer authentication et JSON Web Token


Pour qu'une application distante soit autorisée à utiliser un service Web, il est possible de travailler avec un mécanisme de jeton.

On appellera ce mécanisme Bearer authentication (littéralement authentification du porteur) ou Token authentication.

En gros, le fonctionnement va comme suit :

  1. Pendant une session de travail, la première fois que l'application distante a besoin du service Web, elle lui fournit des informations d'authentification (code d'usager - mot de passe).
  2. Lorsqu'il détecte qu'il a reçu un code d'usager et un mot de passe, le service Web vérifie ces informations et, si elles sont valides, il retourne un jeton.
    1. Le jeton peut être une simple chaîne générée du côté serveur, par exemple avec random_bytes().
    2. Pour plus de sécurité, on peut utiliser un jeton Web JSON (JSON Web Token ou JWT). Il s'agit ici encore d'une chaîne générée par le serveur mais cette chaîne contient des informations qui sont cryptées. La chaîne est en fait composée de trois parties : l'en-tête (header), les données (charge utile, payload) et la signature (signature).
  3. Lors des appels suivants, l'application fournit le jeton dans son entête HTTP. Le service Web s'assure que le jeton est valide et si oui, il effectue le travail demandé.

Je vous explique ici comment générer un jeton JWT.

Génération de la clé secrète

Le service Web doit posséder une clé secrète qui sera utilisée pour créer le jeton JWT.

Cette clé secrète, qui ne doit être connue que par le service Web, sera utilisée plus précisément pour hacher la signature du jeton JWT.

Pour générer une clé secrète :

PHP

$secret = bin2hex(random_bytes(32));
echo $secret;

Vous pouvez maintenant mettre ces lignes en commentaire (ou les supprimer) et ajouter la clé secrète dans votre fichier de configurations.

PHP

$secret = 'a930902390832e7090c889d7fe1eea6a5d89e186631a08540ed017a554fe4774';

Génération du jeton par le service Web

En PHP, le jeton peut être généré à l'aide d'une bibliothèque telle que ReallySimpleJWT.

Il est également possible de générer le jeton à l'aide de cet extrait de code inspiré de l'article « Create Your JWTs From Scratch » disponible ici : https://dzone.com/articles/create-your-jwts-from-scratch.

PHP

/**
* Effectue l'encodage en base64 d'une chaîne et la rend propre à être utilisée dans un URL.
* Source : https://dzone.com/articles/create-your-jwts-from-scratch
*
* @param String $text Texte à encoder.
*
* @return string Texte encodé.
*
*/
// PHP has no function, so let's define one that
// does some magic by replacing + with -, / with _ and = with ''.
// This way we can pass the string within URLs without
// any URL encoding.
function base64UrlEncode($text) {
    return str_replace(
        ['+', '/', '='],
        ['-', '_', ''],
        base64_encode($text)
    );
}

/**
* Génère un jeton JWT.
* Inspiré de https://dzone.com/articles/create-your-jwts-from-scratch
*
* @param String $secret Chaîne secrète.
* @param Int $login Code d'authentification de l'usager.
*
* @return string Jeton JWT.
*
*/
function genererJWT($secret, $login) {

    $header = json_encode([
        'typ' => 'JWT',
        'alg' => 'HS256'
    ]);

    $payload = json_encode([
        'login' => $login,
        'exp' => time() + 3600
    ]);

    $base64UrlHeader = base64UrlEncode($header);
    $base64UrlPayload = base64UrlEncode($payload);
    $signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $secret, true);
    $base64UrlSignature = base64UrlEncode($signature);

    $jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;

    return $jwt;
}

Un echo permet de prendre connaissance de la valeur du jeton.

PHP

$jeton = genererJWT($secret, "toto");
echo $jeton;

Vous obtiendrez une chaîne au format eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRvdG8iLCJleHAiOjE3MTA3NzM1Mzd9.VWfTYzfCz39_brOUK7IQtfG407mFIoky6jgm0EKZ4W4

Certaines parties de cette chaîne peuvent être  décryptées : l'entête et la charge utile. Seule la signature est hachée donc indécryptable.

À preuve, vous pouvez décrypter le jeton avec ce petit utilitaire : https://www.jsonwebtoken.io

Décoder un JWT

Vérification du jeton 

Quand le service Web reçoit un jeton JWT, il peut utiliser cette fonction pour valider le jeton.

PHP

/**
* Vérifie si un jeton JWT est valide.
* Inspiré de https://dzone.com/articles/create-your-jwts-from-scratch
*
* @param String $secret Chaîne secrète.
* @param String $jwt Jeton à valider.
*
* @return Bool True si le jeton est valide.
*
*/
function validerJWT($secret, $jwt) {

    $tokenParts = explode('.', $jwt);
    $header = base64_decode($tokenParts[0]);
    $payload = base64_decode($tokenParts[1]);
    $signatureProvided = $tokenParts[2];

    // check the expiration time - note this will cause an error if there is no 'exp' claim in the token
    $now = time();
    $tokenExpired = ($now - json_decode($payload)->exp) > 0;

    // build a signature based on the header and payload using the secret
    $base64UrlHeader = base64UrlEncode($header);
    $base64UrlPayload = base64UrlEncode($payload);
    $signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $secret, true);
    $base64UrlSignature = base64UrlEncode($signature);

    // verify it matches the signature provided in the token
    $signatureValid = ($base64UrlSignature === $signatureProvided);

    return !$tokenExpired && $signatureValid;
}

 

▼Publicité

Veuillez noter que le contenu de cette fiche vous est partagé à titre gracieux, au meilleur de mes connaissances et sans aucune garantie.
Merci de partager !
Soumettre