Passeport Express (node.js) traitement des erreurs

j'ai regardé comment la gestion des erreurs devrait fonctionner dans le noeud via cet échange de pile , mais je ne suis pas sûr de ce que fait passport quand il échoue l'authentification. J'ai la stratégie locale suivante:

passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' },
  function(email, password, next) {

    User.find({email: UemOrUnm}, function(err, user){
      if (err) { console.log('Error > some err'); return next(err); }
      if (!user) { console.log('Error > no user'); return next('Incorrect login or password'); } 

      if (password != user.password) {
        return next(Incorrect login or password);
      }
      return next(null, user);
    });
  }
));

après que j'ai vu "erreur > une erreur" sur l'impression de la console, rien d'autre ne se produit. Je pense qu'elle devrait continuer sur le prochain chemin avec un paramètre d'erreur, mais il ne semble pas à le faire. Ce qui se passe?

59
demandé sur Community 2013-03-30 00:44:23

3 réponses

La stratégie de mise en œuvre fonctionne en conjonction avec passport.authenticate à la fois pour authentifier une demande, et la poignée de réussite ou d'échec.

dire que vous utilisez cette route (qui est passé une adresse e-mail et un mot de passe):

app.post('/login', passport.authenticate('local', {
  successRedirect: '/loggedin',
  failureRedirect: '/login', // see text
  failureFlash: true // optional, see text as well
});

cela s'appellera le code dans la stratégie, où l'une des trois conditions peut se produire:

  1. Une erreur interne s'est produite en essayant de récupérer les informations des utilisateurs (dire le la connexion à la base de données est terminée); cette erreur serait transmise: next(err) ; elle sera traitée par Express et générera une réponse HTTP 500;
  2. les informations d'identification fournies sont invalides (il n'y a pas d'utilisateur avec l'adresse e-mail fournie, ou le mot de passe est une inadéquation); dans ce cas, vous ne générez pas d'erreur, mais vous passez un false comme objet utilisateur: next(null, false) ; cela déclenchera le failureRedirect (si vous n'en définissez pas une, une réponse non autorisée HTTP 401 être générés);
  3. on a Tout vérifié, vous avez un utilisateur valide de l'objet, de sorte que vous passer: next(null, user) ; cela va déclencher la successRedirect ;

dans le cas d'une authentification invalide (mais pas une erreur interne), vous pouvez passer un message supplémentaire avec le rappel:

next(null, false, { message : 'invalid e-mail address or password' });

si vous avez utilisé failureFlash et installé le middleware connect-flash , le message est stocké dans la session et peut être facilement accessible, par exemple, être utilisés dans un modèle.

EDIT: il est également possible de gérer complètement le résultat du processus d'authentification vous-même (au lieu de passeport d'envoyer une redirection ou 401):

app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) {
      return next(err); // will generate a 500 error
    }
    // Generate a JSON response reflecting authentication status
    if (! user) {
      return res.send({ success : false, message : 'authentication failed' });
    }
    // ***********************************************************************
    // "Note that when using a custom callback, it becomes the application's
    // responsibility to establish a session (by calling req.login()) and send
    // a response."
    // Source: http://passportjs.org/docs
    // ***********************************************************************
    req.login(user, loginErr => {
      if (loginErr) {
        return next(loginErr);
      }
      return res.send({ success : true, message : 'authentication succeeded' });
    });      
  })(req, res, next);
});
145
répondu robertklep 2016-01-15 07:53:16

ce que Christian disait était vous devez ajouter la fonction

req.login(user, function(err){
  if(err){
    return next(err);
  }
  return res.send({success:true});
});

donc toute la route serait:

app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) {
      return next(err); // will generate a 500 error
    }
    // Generate a JSON response reflecting authentication status
    if (! user) {
      return res.send(401,{ success : false, message : 'authentication failed' });
    }
    req.login(user, function(err){
      if(err){
        return next(err);
      }
      return res.send({ success : true, message : 'authentication succeeded' });        
    });
  })(req, res, next);
});

source: http://passportjs.org/guide/login/

16
répondu cpoole 2015-12-17 13:17:09

vous devez ajouter req.logIn(function (err) { }); et faire le succès rediriger à l'intérieur de la fonction de rappel

2
répondu Christian Nagorka 2015-02-20 17:46:37