Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Problème 8 – Déconnexion

Les instructions suivantes indiquent les modifications à apporter au Prototype de niveau 5 pour atteindre le Prototype de niveau 6.

Etape 1: Installer les paquets

$ npm install --save uuid redis

Etape 2: Identifier les JWT

Afin de pouvoir maintenir une liste de jetons révoqués, nous devons être en mesure de les identifier. Pour cela, il suffit d’attribuer un numéro unique (UUID) à chaque jeton dans l’attribut JTI (Json web Token Identifier). Nous devons donc modifier le code d’émission des jetons JWT dans le fichier routes/signin.js :

// Import JWT module and UUID tool
const jwt = require('jsonwebtoken');
const uuidv4 = require('uuid/v4')



  // Define the JWT Identifier with a UUID
  let jti = uuidv4();

  // sign the token
  let token = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '10m', jwtid: jti, algorithm: 'HS512'});

Chaque jeton aura désormais son propre identifiant sous la forme « bdc447d7-5e6b-479c-a434-ce707bb81a10 ». Cet identifiant sera utilisé comme clé dans notre liste noire.

Etape 3 : Serveur Redis

Il faut maintenant que l’application se connecte à notre serveur Redis. Il suffit d’intégrer le code suivant dès le début du fichier app.js :

// Setup Redis
const MyRedis = require('redis');
const MyRedisClient = MyRedis.createClient();

MyRedisClient.on('connect', function(){
    console.log('Successfully connected to Redis');
});

MyRedisClient.on('error', function(err) {
     console.log('Redis error: ' + err);
     process.exit();
});

Etape 4 - Révoquer les jetons

Lorsque l’utilisateur se déconnecte, il faut ajouter le jeton dans la liste noire stockée sur le serveur Redis. Pour cela, il suffit de modifier le fichier routes/signout.js :

// Redis Setup
const MyRedis = require('redis');
const MyRedisClient = MyRedis.createClient();

// Signout page
router.get('/', function(req, res) {

  // Add JWT in the blacklist and set expiration time
  MyRedisClient.set(req.user.jti,'1');
  MyRedisClient.expireat(req.user.jti, req.user.exp);
  
  res.redirect('/');
});

Redis nous permet d’indiquer la durée de conservation souhaitée. Nous n’aurons ainsi pas besoin d’implémenter un mécanisme de purge pour supprimer les jetons expirés. La taille de la liste noire en sera ainsi limitée.

Etape 5 - Vérifier si un jeton est révoqué

Lorsqu’un utilisateur demande l’accès à une route soumise à une authentification par jeton, nous devons nous assurer que le jeton est valide. Le jeton doit donc avoir une signature valide et ne pas avoir été révoqué. Pour cela, nous modifions la fonction de vérification dans le fichier config/MyPassport.js afin de rechercher le jeton dans la base de données Redis :

// Redis Setup
const MyRedis = require('redis');
const MyRedisClient = MyRedis.createClient();

// Configure the cookie Strategy for Passport
MyPassport.use(new MyCookieStrategy(

  function (token, done) {
    
    // Check JWT
    jwt.verify(token, process.env.JWT_SECRET, function(err, payload) {
      
      // If checking failed
      if (err) {
        return done(err);
      }
      
      // If user is empty
      if (!payload){
        return done(null, false);
      }
      
     // If token is revoked
         MyRedisClient.get(payload.jti, function (err, value) {
        
         // If checking failed
        if (err) {
          return done(err);
        }
      
        // If JWT is revoked
        if (value !== null) {
          console.log("JWT " + payload.jti + "is revoked !");
          return done(null, false);
        }
    
        // If everything all right, the user will be authenticated
        return done(null, payload);
        
      });

  });
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment