Que sont les jetons Web JSON (JWT) ? Pourquoi les API les utilisent-elles ?

Que sont les jetons Web JSON (JWT) ? Pourquoi les API les utilisent-elles ?

La norme JSON Web Tokens (JWT) décrit une méthode compacte pour le transfert de données vérifiable. Chaque jeton contient une signature qui permet à la partie émettrice de vérifier l’intégrité du message.

Dans cet article, vous apprendrez ce que comprend le framework JWT et comment vous pouvez créer vos propres jetons personnalisés. JWT est un moyen populaire de sécuriser les API et d’authentifier les sessions utilisateur, car elles sont simples et autonomes.

Comment fonctionnent les JWT

L’une des tâches les plus courantes de toute API consiste à vérifier que les utilisateurs sont bien ceux qu’ils prétendent être. L’authentification est généralement effectuée lorsque le client inclut une clé API avec les requêtes qu’il envoie au serveur. La clé contient des informations intégrées qui identifient l’utilisateur. Cela laisse encore une grande question : comment le serveur peut-il vérifier qu’il a émis la clé en premier lieu ?

Les JWT résolvent facilement ce problème en utilisant un secret pour signer chaque jeton. Le serveur peut vérifier la validité du jeton en tentant de recalculer la signature soumise à l’aide de son secret privé. Toute interférence entraînera l’échec de la vérification.

Format JWT

Les JWT sont constitués de trois composants distincts :

  • En-tête – inclut des métadonnées sur le jeton lui-même, telles que l’algorithme de signature utilisé.
  • Charge utile – La charge utile d’un jeton peut être n’importe quelle donnée arbitraire liée à votre système. Il peut inclure un ID utilisateur et une liste de fonctionnalités avec lesquelles l’utilisateur peut interagir.
  • Signature – La signature vous permet de vérifier l’intégrité du jeton à l’avenir. Il est créé en signant l’en-tête et la charge utile à l’aide d’une valeur secrète connue uniquement du serveur.

Ces trois composants sont combinés avec des points pour obtenir le JWT :

header.payload.signature

Chaque partie est encodée en Base-64. Un jeton complet est une chaîne de texte qui peut être facilement utilisée dans des environnements de programmation et envoyée avec des requêtes HTTP.

Créer un JWT

Les étapes de création d’un JWT peuvent être implémentées dans tous les langages de programmation. Cet exemple utilise PHP, mais le processus sera similaire sur votre propre système.

Commencez par créer un en-tête. Cela comprend généralement deux champs alget typ:

  • alg– L’algorithme de hachage qui sera utilisé pour créer la signature. Il s’agit généralement de HMAC SHA256 ( HS256).
  • typ– Type de jeton généré. Ça devrait être JWT.

Voici le JSON définissant l’en-tête :

L’en-tête JSON doit être encodé en Base64 comme ceci :

Définissez ensuite votre charge utile de jeton comme un autre objet JSON. Cela dépend de l’application. L’exemple fournit des informations sur le compte de l’utilisateur authentifié, ainsi que des informations sur le jeton lui-même. exp, iatet nbfsont des champs utilisés par convention pour spécifier l’heure d’expiration d’un jeton émis à l’heure et invalidé avant l’heure (initiale). La charge utile doit également être encodée en Base64.

Il ne reste plus qu’à créer une signature. Pour créer cela, vous devez d’abord concaténer l’en-tête et la charge utile dans une chaîne séparée par des caractères. :

Vous devez ensuite générer un secret unique à utiliser comme clé de signature. Le secret doit être stocké en toute sécurité sur votre serveur et ne doit jamais être envoyé aux clients. L’exposition de cette valeur permettra à quiconque de créer des jetons valides.

Vous terminez le processus en utilisant le secret pour signer l’en-tête combiné et la chaîne de charge utile à l’aide de l’algorithme de hachage spécifié dans l’en-tête. La signature de sortie doit être encodée en Base64 comme les autres composants.

Vous avez maintenant le titre, la charge utile et la légende en tant que composants de texte distincts. Concaténez-les tous avec des .délimiteurs pour créer un JWT à envoyer à votre client :

Validation des JWT entrants

L’application client peut déterminer les fonctionnalités disponibles pour l’utilisateur en décodant la charge utile du jeton. Voici un exemple JavaScript :

Un attaquant peut comprendre que ces données sont en texte brut et semblent facilement modifiables. Ils peuvent essayer de convaincre le serveur qu’ils disposent d’une fonctionnalité bonus en modifiant la charge utile du jeton dans leur prochaine requête :

La réponse à la question de savoir comment le serveur se défend contre ces attaques réside dans la méthode utilisée pour générer la signature. La valeur de la signature prend en compte l’en-tête et la charge utile du jeton. Changer la charge utile, comme dans cet exemple, signifie que la signature n’est plus valide.

Le code du serveur valide les JWT entrants en recalculant leurs signatures. Le jeton a été falsifié si la signature envoyée par le client ne correspond pas à la valeur générée sur le serveur.

Un attaquant ne peut pas générer de jeton valide sans accéder au secret du serveur. Cela signifie également que la perte accidentelle – ou la rotation délibérée – d’un secret invalidera immédiatement tous les jetons précédemment émis.

Dans une situation réelle, votre code d’authentification doit également vérifier l’expiration et les horodatages « pas avant » dans la charge utile du jeton. Ils sont utilisés pour déterminer si la session d’un utilisateur est valide.

Quand utiliser JWT

Les JWT sont souvent utilisés pour l’authentification API car ils sont faciles à mettre en œuvre sur le serveur, faciles à utiliser sur le client et faciles à transférer au-delà des limites du réseau. Malgré leur simplicité, ils disposent d’une bonne sécurité car chaque jeton est signé à l’aide de la clé privée du serveur.

JWT est un mécanisme sans état, vous n’avez donc pas besoin d’enregistrer des informations sur les jetons émis sur votre serveur. Vous pouvez obtenir des informations sur le client représentant le JWT à partir de la charge utile du jeton au lieu d’effectuer une recherche dans la base de données. Ces informations sont fiables une fois la signature du jeton vérifiée.

L’utilisation de JWT est un bon choix lorsque vous avez besoin d’échanger des informations entre deux parties sans risque d’interférence. Cependant, il y a des faiblesses dont il faut être conscient : l’ensemble du système sera compromis si la clé privée de votre serveur est divulguée ou si votre code de vérification de signature est bogué. Pour cette raison, de nombreux développeurs préfèrent utiliser une bibliothèque open source pour implémenter la génération et la validation JWT. Des options sont disponibles pour tous les langages de programmation courants. Ils éliminent le risque d’oubli lorsque vous vérifiez vous-même les jetons.

Sommaire

La norme JWT est un format d’échange de données qui inclut une vérification d’intégrité intégrée. Les JWT sont couramment utilisés pour sécuriser la communication entre les serveurs d’API et les applications clientes. Le serveur peut faire confiance aux jetons entrants s’il peut reproduire leurs signatures. Cela vous permet d’effectuer des actions en toute sécurité en utilisant les informations obtenues à partir de la charge utile du jeton.

Les JWT sont pratiques, mais ils présentent certains inconvénients. La représentation textuelle encodée en Base64 d’un JWT peut rapidement devenir volumineuse si vous avez plusieurs champs de charge utile. Cela peut devenir une surcharge inacceptable lorsque votre client doit envoyer un JWT avec chaque demande.

L’apatridie des JWT est également un autre inconvénient potentiel : une fois émis, les jetons sont immuables et doivent être utilisés tels quels jusqu’à leur expiration. Les clients qui utilisent des charges utiles JWT pour déterminer les autorisations des utilisateurs ou les fonctionnalités sous licence devront recevoir un nouveau jeton du serveur principal chaque fois que leurs affectations changent.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *