
Partager:
Acteur de formation avec une thèse sur la comédie, je suis venu au développement PHP par le biais de la scène des rencontres. Vous pouvez me trouver en train de parler et d'écrire sur la technologie, ou de jouer/acheter des disques bizarres de ma collection de vinyles.
Les JWT : Qu'est-ce que c'est au juste ?
L'un des principes que l'équipe Developer Experience respecte lors de la rédaction des tutoriels est qu'il ne faut ne jamais supposer que les gens connaissent un sujet technique. C'est quelque chose que j'ai tendance à oublier et que je dois me rappeler régulièrement. Si vous ressentez un jour ce sentiment de culpabilité de l'autre côté de l'équation, je trouve toujours pratique de revenir à ce diagramme de Venn toujours d'actualité :

Travailler avec des JWTs constamment, quotidiennement, dans le cadre de mon travail, en développant notre SDK PHP, est l'un de ces sujets. Une fois que je me suis renseigné sur la façon dont nous utilisons les JWT, je me suis arrêté là. Mais.., avec mon principe de "ne jamais présumer de ses connaissances", je réalise qu'il y a beaucoup de gens qui n'ont aucune idée de ce que c'est. En outre, certains développeurs ayant une certaine expérience (même dans la construction et la consommation d'API) ne les ont pas encore utilisés ou n'en ont même pas entendu parler. Le rythme d'évolution des technologies API a tendance à être beaucoup plus lent dans les grandes entreprises ou les entreprises à grande échelle que beaucoup ne le pensent. Nous sommes en 2023 au moment de la rédaction de cet article, et pourtant de nombreuses banques et entreprises pharmaceutiques utilisent encore SOAP.
Avant de nous plonger dans l'anatomie des JWT, il convient de noter que cet article comporte des exemples avec du code. Si vous souhaitez utiliser certains de nos outils pour créer des JWTs, rendez-vous sur cet article de Benjamin Aronov qui vous montre comment en générer un entièrement dans le tableau de bord de Vonage.
Les bases
JWT est l'acronyme de JSON Web Token. Dans un scénario d'acronyme spaghetti légèrement confus, il s'agit techniquement de JavaScript Object Notation Web Token dans sa forme complète. Jusqu'à son introduction dans un projet daté de juillet 2011, les formes les plus courantes d'authentification pour les API web étaient l'ajout d'une clé API et d'un secret en clair dans la chaîne de requête d'une demande ou l'authentification de base dans laquelle une clé API ou un secret (ou les deux) sont hachés, généralement avec un encodage base64 et transmis en tant qu'en-tête. Un JWT est un hachage inclus dans l'en-tête d'une requête (ou dans le corps de la requête, mais c'est moins courant), qui remplace les anciens styles d'authentification.
Authentification existante : Les inconvénients
Pourquoi donc une nouvelle technique d'authentification ?
Sécurité
Il s'agit là du facteur le plus important. L'envoi d'une clé API ou d'un secret en clair dans l'en-tête (ou la chaîne de requête) pour chaque demande ouvre un vecteur de sécurité assez important. Il y a plus de trafic avec les mêmes informations d'identification ouvertes au reniflage, et dès que ces clés sont compromises, vous avez ouvert l'ensemble de votre application ou de votre Account.
L'authentification de base, qui consiste à prendre {nom d'utilisateur}:{mot de passe} sous la forme d'une chaîne et à l'encoder en base64, tend à être un piège. De nombreux développeurs novices en matière d'authentification API pourraient voir le hachage résultant et penser "Cela semble sûr !", mais la réalité est qu'il est facilement décodé en ses deux parties secrètes. Par exemple, rendez-vous à l'adresse https://emn178.github.io/online-tools/base64_decode.html et collez-y c2VlLXRoYXQtd2FzOmVhc3k=.
La seule véritable couche de sécurité que vous pouvez créer en utilisant ces méthodes est la rotation de vos clés. En fonction de votre produit API, les bases de code héritées peuvent ne même pas avoir la capacité de faire tourner une combinaison clé principale/secret (en particulier si elles sont liées directement à un compte lors de la création du compte).
Champ d'application
Auparavant, avec les types d'authentification de base, de nouvelles clés étaient ajoutées à un portefeuille en plus de clés primaires, que vous créiez généralement à l'aide d'un ensemble de scopes. Il peut en résulter une collection assez vaste de clés utilisées pour divers produits ou pour des requêtes spécifiques - la rotation périodique d'un grand nombre de clés peut devenir très encombrante.
Portabilité
Comme pour le champ d'application, les secrets fixes de ce type ont les autorisations des utilisateurs, les champs d'application et l'accès à l'API stockés dans le serveur. Cela les rend statiques et peu flexibles lorsque vous avez une API plus complexe avec de nombreux paramètres à prendre en compte lors de la réception d'une requête.
Anatomie d'un JWT
Les JWT visent à répondre à ces trois préoccupations. Voici comment ils sont structurés :
Informations sur l'en-tête
Lorsque nous parlons d'"en-tête", il convient de noter qu'il s'agit de l'en-tête du JWT. de l'en-tête du JWT et non d'un en-tête de requête HTTP.
Le serveur a besoin d'informations sur la manière dont le JWT a été créé. En conséquence, l'en-tête contiendra des informations sur la façon dont le JWT a été créé en deux clés :
algqui, dans de nombreux cas, est susceptible de passer par défaut à la norme HS256typqui identifie le jeton comme étant un JWT (au fur et à mesure que la norme évolue, il est probable qu'il y ait des itérations ou de nouvelles versions du type de jeton).
Charge utile
La charge utile d'un JWT se présente sous la forme de revendicationsqui sont une série de paires clé-valeur contenant des informations sur le JWT. Les noms réservés (ou *Registered Claim Names) les plus courants sont les suivants :
iss: la source du JWT (application, organisation, etc.)sub: une valeur unique pour l'émetteur, à laquelle les autres revendications se réfèrent dans le contexte du JWT.expla date d'expiration du JWTiat: date à laquelle le JWT a été créé (émis à)jti: un identifiant unique pour ce JWT
Les JWT sont si pratiques pour l'authentification parce que vous pouvez leur ajouter des revendications personnalisées qui sont pertinentes pour l'application qui les consomme. Prenons, par exemple, le JWT de le JWT de Vonage - Lorsque vous utilisez nos API qui prennent en charge l'authentification JWT, une revendication personnalisée, application_id est utilisée. Vonage peut vérifier le JWT par rapport à la clé SSH privée de votre Account (qui aura été utilisée par le client de la demande pour générer le JWT), et s'il est valide, la demande peut être rapidement acheminée vers l'instance d'application correcte au sein des API de Vonage.
Comment créer un JWT : édition PHP
En tant que développeur PHP résident au sein de mon équipe, je vais générer un JWT valide en aussi peu de lignes de code que possible pour montrer à quel point il est relativement simple de commencer. Voici ce dont nous avons besoin :
Un identifiant d'application du tableau de bord.
Une copie de la clé privée de l'application a été téléchargée à partir du tableau de bord.
Vous pouvez obtenir les deux dans les paramètres de l'application ici :

Nous utiliserons pour cela le PHP JWT creator de Vonage sur GitHub. Pour l'installer, vous aurez besoin de composer.
Et maintenant, le code :
<?php
require_once "vendor/autoload.php";
$applicationId = "78d335fa-323d-0114-9c3d-d6f0d48968cf";
$privateKey = file_get_contents('private.key');
$generator = new Vonage\JWT\TokenGenerator($applicationId, $privateKey);
$jwt = $generator->generate();
C'est fait !
Pour l'utiliser dans une demande, vous devez l'ajouter en tant qu'en-tête. Nous avons besoin d'un fichier conforme à la PSR-18 HTTP compatible PSR-18 pour l'envoyer. J'ai choisi le HTTPClient de Symfony pour montrer le peu de lignes dont nous disposons. Pour les installer, ajoutez-les à votre projet avec composer :
Ensuite, nous allons envoyer une requête à l'API des messages de Vonage. Vonage Messages API en utilisant notre JWT :
use Symfony\Component\HttpClient\HttpClient;
$payload = [
'message_type' => 'text',
'text' => 'Using a JWT to send Vonage a request!',
'to' => '44779999999',
'from' => '44779499999',
'channel' => 'sms'
]
$client = HttpClient::create();
$client->request('POST', 'https://api.nexmo.com/v1/messages/', [
'headers' => [
'Authorization' => 'Bearer ' . $jwt,
'Content-Type' => 'application/json',
],
'json' => $payload
])
Et voilà ! Bien sûr, il s'agit d'un exemple brut de la façon de procéder. Si vous souhaitez réaliser une intégration complète, je vous recommande d'utiliser notre SDK Core PHP, qui gère de nombreux problèmes. Si PHP n'est pas votre choix, ce n'est pas grave ! Nous avons également des SDK Node, Java, Python, Ruby et NET !
Partager:
Acteur de formation avec une thèse sur la comédie, je suis venu au développement PHP par le biais de la scène des rencontres. Vous pouvez me trouver en train de parler et d'écrire sur la technologie, ou de jouer/acheter des disques bizarres de ma collection de vinyles.