web-dev-qa-db-fra.com

Traitement des erreurs Express Passport (node.js)

J'ai examiné la façon dont 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 le passeport lorsqu'il échoue à l'authentification. J'ai la LocalStrategy 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);
    });
  }
));

Une fois que je vois l'impression "Erreur> quelque erreur" sur la console, rien ne se passe. Je pense que cela devrait continuer sur le prochain chemin avec un paramètre d'erreur, mais cela ne semble pas le faire. Que se passe-t-il?

64
Omid Ahourai

La stratégie d'implémentation fonctionne conjointement avec passport.authenticate Pour authentifier une demande et gérer le succès/l'échec.

Supposons que vous utilisiez cet itinéraire (auquel une adresse e-mail et un mot de passe sont transmis):

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

Cela appellera le code dans la stratégie, où l’une des trois conditions suivantes peut être remplie:

  1. Une erreur interne s'est produite lors de la récupération des informations des utilisateurs (par exemple, la connexion à la base de données a disparu); cette erreur serait transmise à: next(err); cela sera géré par Express et générera une réponse HTTP 500;
  2. Les informations d'identification fournies ne sont pas valides (aucun utilisateur ne possède l'adresse de messagerie fournie ou le mot de passe est incompatible); dans ce cas, vous ne générez pas d'erreur, mais vous transmettez un false en tant qu'objet utilisateur: next(null, false); cela déclenchera le failureRedirect (si vous n'en définissez pas un, une réponse HTTP 401 non autorisée sera générée);
  3. Tout vérifie, vous avez un objet utilisateur valide, vous le transmettez donc: next(null, user); cela déclenchera le successRedirect;

En cas d'authentification invalide (mais pas d'erreur interne), vous pouvez transmettre 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 fourni est stocké dans la session et est facilement accessible, par exemple. exemple, être utilisé dans un modèle.

EDIT: Il est également possible de gérer complètement le résultat du processus d'authentification (à la place de l'envoi par Passport d'une redirection ou de 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);
});
156
robertklep

Ce que Christian disait, il faut ajouter la fonction

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

Donc tout l'itinéraire 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/

18
cpoole

Vous devez ajouter req.logIn(function (err) { }); et effectuer la redirection de succès dans la fonction de rappel.

2
Christian Nagorka