web-dev-qa-db-fra.com

passeport local avec node-jwt-simple

Comment combiner passeport local pour renvoyer un jeton JWT en cas d'authentification réussie?

Je veux utiliser node-jwt-simple et regarder passport.js Je ne suis pas sûr de savoir comment s'y prendre.

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

Est-il possible de renvoyer le jeton lors de l'appel de done ()? Quelque chose comme ça ... (juste un pseudo code)

if(User.validCredentials(username, password)) {
  var token = jwt.encode({username: username}, tokenSecret);
  done(null, {token : token}); //is this possible?
}

Si non, comment puis-je retourner le jeton?

87
cgiacomi

Je l'ai compris!

Tout d'abord, vous devez mettre en œuvre la bonne stratégie. Dans mon cas, LocalStrategy, et vous devez fournir votre logique de validation. Par exemple, utilisons celui de passport-local.

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

le rappel de vérification que vous fournissez function(username, password, done) se chargera de trouver votre utilisateur et de vérifier si le mot de passe correspond (au-delà de la portée de la question et de ma réponse)

passport.js attend plusieurs éléments pour que cela fonctionne, l'un d'eux consiste à renvoyer l'utilisateur dans la stratégie. J'essayais de changer cette partie du code et c'était faux. Le rappel attend false si la validation échoue et un object (l'utilisateur validé) si vous réussissez.

Maintenant .... comment intégrer JWT?

Dans votre itinéraire de connexion, vous devrez gérer une authentification réussie ou non réussie. Et c'est ici que vous devez ajouter la création de jeton JWT. Ainsi:

(N'oubliez pas de désactiver la session, sinon vous devrez implémenter les fonctions sérialiser et désérialiser. Et vous n'en aurez pas besoin si vous ne persistez pas dans la session, ce que vous ne ferez pas si vous utilisez une authentification basée sur un jeton)

Exemples locaux de passeport: (avec le jeton JWT ajouté)

// POST /login
//   This is an alternative implementation that uses a custom callback to
//   achieve the same functionality.
app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err) }
    if (!user) {
      return res.json(401, { error: 'message' });
    }

    //user has authenticated correctly thus we create a JWT token 
    var token = jwt.encode({ username: 'somedata'}, tokenSecret);
    res.json({ token : token });

  })(req, res, next);
});

Et c'est ça! Maintenant, lorsque vous appelez/connectez-vous et POST nom d'utilisateur et mot de passe (toujours sur SSL)), le premier extrait de code ci-dessus tente de trouver un utilisateur en fonction du nom d'utilisateur que vous avez fourni, puis vérifiez que le correspondances de mot de passe (bien sûr, vous devrez changer cela pour répondre à vos besoins).

Après cela, votre itinéraire de connexion sera appelé et vous pourrez alors vous charger de renvoyer une erreur ou un jeton valide.

J'espère que cela aidera quelqu'un. Et si j'ai commis des erreurs ou oublié quelque chose, faites-le-moi savoir.

122
cgiacomi

C'est une excellente solution, je veux juste ajouter ceci:

var expressJwt = require('express-jwt');

app.use('/api', expressJwt({secret: secret}));

J'aime utiliser "express-jwt" pour valider le jeton.

au fait: cet article est excellent pour apprendre à gérer le jeton côté client, en utilisant Angular, afin de le renvoyer à chaque demande.

https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

18
ZeroCR

Voici une plaque chauffante sur laquelle je travaille pour utiliser spécifiquement des jetons api (pas de sessions ... pas cette session ne sont mauvaises bien sûr; nous utilisons simplement l'approche par jetons): https://github.com/roblevintennis/passport-api-tokens

3
Rob