Connexion

L'authentification par jeton simplifiée

Découvrez l'authentification par jeton et comment intégrer le protocole JWT dans vos applications.

token-based-authentication-made-easy

Authentification par jeton

Un jeton est un élément de données qui n'a aucune signification ou utilité en soi. Cependant, lorsqu'il est associé au bon système de tokenisation, il devient un acteur essentiel de la sécurisation de votre application. L'authentification par jeton garantit que chaque demande adressée à un serveur est accompagnée d'un jeton signé. Le serveur vérifie son authenticité et ne répond qu'ensuite à la demande.

JSON Web Token (JWT) est une norme ouverte (RFC 7519) qui définit une méthode compacte et autonome de transmission sécurisée entre parties d'informations encodées sous forme d'objet JSON. JWT a acquis une grande popularité largement due à sa taille compacte et sa facilité de transmission des jetons via des chaînes de requête, des attributs d'en-tête, intégrés dans le corps d'une demande POST.

Souhaitez-vous familiariser avec les JWT dès que possible ? TÉLÉCHARGER L'E-BOOK GRATUIT

Pourquoi utiliser des jetons?

Les jetons offrent de nombreux avantages par rapport aux méthodes traditionnelles, telles que les cookies.

  • Les jetons sont sans état. Le jeton est autonome. Il contient toutes les informations nécessaires à l'authentification. Cet avantage est important pour l'évolutivité, car votre serveur n'a plus à stocker l'état de la session.
  • Les jetons peuvent être générés n'importe où. La génération de jetons est séparée de la vérification des jetons. Par conséquent, vous pouvez gérer la signature des jetons sur un serveur distinct ou même par l'intermédiaire d'un autre prestataire, comme Auth0.
  • Contrôle d'accès avec granularité fine. Dans la charge utile du jeton, vous pouvez facilement spécifier des rôles et des autorisations pour l'utilisateur, avec des ressources mises à sa disposition.

Ce ne sont là que quelques-uns des avantages offerts par les jetons JSON Web Token. Pour en savoir plus, consultez cet article de blog qui approfondit la question. Il compare les jetons aux cookies en termes de gestion de l'authentification.

Anatomie d'un jeton JSON Web Token

Un jeton JSON Web Token est structuré en trois sections : En-tête, charge utile et signature. L'en-tête et la charge utile sont codés en Base64, puis concaténés par un simple point. Enfin le résultat est signé algorithmiquement pour créer le jeton au format header.claims.signature. L'en-tête se compose de métadonnées, notamment le type de jeton et l'algorithme de hachage utilisé pour signer le jeton. La charge utile contient les données des revendications que le jeton code. Le résultat final ressemble à ceci :

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJtZXNzYWdlIjoiSldUIFJ1bGVzISIsImlhdCI6MTQ1OTQ0ODExOSwiZXhwIjoxNDU5NDU0NTE5fQ.-yIVBD5b73C75osbmwwshQNRC7frWUYrqaTjTpza2y4

La signature des jetons les protège contre la manipulation, alors qu'ils ne sont pas cryptés. Cela signifie qu'un jeton peut être facilement décodé et son contenu révélé. Une fois sur le site jwt.io, nous pouvons coller le jeton ci-dessus. Nous pouvons alors immédiatement lire l'en-tête et la charge utile. Cependant, sans le code secret correct, le jeton est inutile. En effet, le message « Invalid Signature » s'affiche. Si nous ajoutons le bon code secret, dans cet exemple, la chaîne L3@RNJWT, le message « Signature Verified » s'affiche.

Décodage d'un JWT avec JWT.io

Dans un scénario réel, un client envoie une demande au serveur et transmet le jeton avec cette dernière. Le serveur tente de vérifier le jeton et, en cas de succès, poursuit le traitement de la demande. Si le serveur ne peut pas vérifier le jeton, il envoie un message 401 Unauthorized. La demande ne peut donc pas être traitée, car l'autorisation n'a pas pu être vérifiée.

Bonnes pratiques concernant les jetons JSON Web Token

Avant de passer à la mise en œuvre de JWT, voyons maintenant quelques bonnes pratiques qui garantiront que l'authentification basée sur les jetons est correctement mise en œuvre dans votre application.

  • Gardez le secret... secret. Et protégez-le. La clé de la signature doit être traitée comme n'importe quel autre justificatif d'identité. Elle ne doit être révélée qu'aux services qui en ont absolument besoin.
  • N'ajoutez aucune donnée sensible à la charge utile. La signature des jetons les protège contre la manipulation. Ils sont faciles à décoder. Ajoutez le nombre minimum de revendications à la charge utile pour obtenir les meilleures performances et la meilleure sécurité.
  • Définissez la durée de vie des jetons. Techniquement, une fois le jeton signé, il est valable pour toujours, sauf si la clé de signature est modifiée ou si sa date d'expiration est explicitement définie. Cela peut poser des problèmes potentiels. Une stratégie d'expiration et/ou de révocation des jetons doit donc être définie.
  • Adoptez le protocole HTTPS. N'envoyez pas de jetons sur des connexions non HTTPS, car ces demandes peuvent être interceptées et les jetons compromis.
  • Prenez en compte toutes les études de cas des autorisations. L'ajout d'un système secondaire de vérification des jetons pour vérifier que les jetons ont été générés sur votre serveur, par exemple, n'est peut-être pas une pratique courante, mais peut s'avérer nécessaire pour répondre à vos besoins.

Pour plus d'informations et les bonnes pratiques, consultez l'article du blog : 10 choses à savoir sur les jetons.

L'authentification par jeton simplifiée

L'authentification par jeton et JWT sont largement pris en charge. JavaScript, Python, C#, Java, PHP, Ruby, Go et d'autres langages de programmation offrent des bibliothèques pour signer et vérifier facilement les jetons JSON Web Token. Implémentons une API pour voir avec quelle rapidité elle peut être sécurisée en utilisant JWT.

Nous avons choisi de développer notre API avec NodeJS, pour limiter la configuration au minimum. Examinons le code de notre implémentation avec JWT.

// Charger nos dépendances
var express = require('express');
var jwt = require('jsonwebtoken');

var app = express();

// Enregistrer la route initiale qui affiche un message de bienvenue.
// Cette route est accessible sans jeton
app.get('/', function(req, res){
  res.send('Bienvenue sur notre API');
})

//Enregistrer la route pour créer un nouveau jeton
// Dans un scénario réel, nous authentifions les informations d'identification de l'utilisateur
// avant de créer un jeton. Mais pour simplifier l'accès à cette route
// nous créons un nouveau jeton qui restera valide pendant 2 minutes.
app.get('/token', function(req, res){
  var token = jwt.sign({username:'ado'}, 'supersecret',{expiresIn: 120});
  res.send(token)
})

// Enregistrer une route qui nécessite un jeton valide pour afficher les données.
app.get('/api', function(req, res){
  var token = req.query.token;
  jwt.verify(token, 'supersecret', function(err, decoded){
    if(!err){
      var secrets = {'accountNumber' : '938291239','pin' : '11289','account' : 'Finance'};
      res.json(secrets);
    } else {
      res.send(err);
    }
  })
})

// Lancer notre appli sur le port 3000
app.listen('3000');

Pour tester notre API actuelle, exécutons l'application et accédons à localhost:3000. Nous verrons seulement le message « Bienvenue sur notre API ». Ensuite, accédez à la route localhost:3000/api. Un message d'erreur JWT indique que nous n'avons pas obtenu de jeton. Accédez à la route localhost:3000/token. Vous constatez d'un nouveau jeton a été créé. Copiez ce jeton, puis accédez à : localhost:3000/api?token={ADD-COPIED-TOKEN-HERE}. La réponse prévue est affichée, à savoir les comptes financiers de l'entreprise.

Avec seulement quelques lignes de code, nous avons correctement sécurisé le point terminal de notre API. Nous n'avons pas encore couvert la gestion de l'authentification correcte de l'utilisateur avant de générer un jeton. C'est ce que nous allons faire ensuite avec Auth0.

Authentification JWT avec Auth0

Nous devrons apporter quelques petites modifications à notre code avant de présenter le flux d'authentification avec Auth0. Examinons ces modifications ci-dessous :

// Charger nos dépendances
var express = require('express');
var jwt = require('express-jwt');

var jwtCheck = jwt({
  secret: new Buffer('{YOUR-APP-SECRET}', 'base64'),
  audience: '{YOUR-APP-CLIENT-ID}'
});

var app = express();

// Plutôt que de vérifier la présence d'un jeton dans notre contrôleur,
// nous utiliserons un middleware pour que, si le jeton n'est pas valide, nous puissions
// interrompre l'exécution de la demande
app.use('/api', jwtCheck);

app.get('/', function(req, res){
  res.send('Bienvenue sur notre API');
})

app.get('/api', function(req, res){
  var secrets = {'accountNumber' : '938291239','pin' : '11289','account' : 'Finance'};
  res.json(secrets);
})

app.listen('3000');

Pour tester le fonctionnement, démarrons le serveur et accédons à localhost:3000/api. Un message indique que nous n'avons pas envoyé de jeton d'autorisation. Allons sur Auth0 Playground, où nous ajoutons nos informations d'identification, afin d'obtenir un jeton. Ajoutez le code suivant sur le Playground :

var domain = '{YOUR-AUTH0-DOMAIN}.auth0.com';
var clientID = '{YOUR-APP-CLIENT-ID}';

var lock = new Auth0Lock(clientID, domain);
lock.show({
  focusInput: false,
  popup: true,
}, function (err, profile, token) {
  alert(token)
});

Pour vérifier que nous pouvons obtenir un jeton, nous devons accéder aux paramètres de notre application dans le Tableau de bord Auth0 et ajouter https://auth0.github.io/playground à notre liste des URL de rappel autorisées. Maintenant, connectons-nous ou créons un compte sur Auth0 Playground. Une fenêtre contextuelle révèle notre jeton.

Le jeton peut être décodé sur jwt.io pour vérifier son contenu. À cette fin, nous aurons besoin du code secret de client pour notre application Auth0. Cochons alors la case : secret base64 encode. Après cela, le message « Signature Verified » devrait s'afficher.

Pour tester que notre API fonctionne avec ce jeton, nous devons transmettre une demande GET à localhost:3000/api et envoyer le jeton dans un en-tête Autorisation. Le plus simple consiste à utiliser une application comme Postman, qui simplifie les tests des points terminaux des API. Lors de l'appel, ajoutez un en-tête Autorisation. Pour la valeur, ajoutez Bearer {TOKEN}. Lorsque l'appel est terminé, le middleware jwtCheck examine la demande, vérifie que l'en-tête Autorisation est conforme au bon format, extrait et vérifie le jeton. Si la vérification est concluante, le reste de la demande est exécuté. Nous avons seulement utilisé les paramètres par défaut pour présenter les capacités de JWT. Vous pouvez en apprendre beaucoup plus dans la section docs.

Étude de cas de l'authentification par jeton

Nous avons vu à quel point il est facile de mettre en œuvre l'authentification JWT et de sécuriser notre API. Pour conclure, examinons les études de cas pour lesquelles l'authentification par jeton est la solution la mieux adaptée.

  • Applications Platform-as-a-Service – Pour exposer les API RESTful consommées par une variété de frameworks et de clients.
  • Applis mobiles – Mise en œuvre d'applis mobiles natives ou hybrides qui interagissent avec vos services.
  • Application Web monopage (SPA) – Création d'applications modernes avec des frameworks, tels qu'Angular et React.

Consultez cette publication pour accéder à des ressources supplémentaires très utiles pour prendre en main les jetons JSON Web Token.

Inscription gratuite

Commencez à construire et à sécuriser vos applis dès aujourd'hui avec la plateforme d'identité Auth0.

3D login box