2013-03-29 12 views
55

Ich habe untersucht, wie die Fehlerbehandlung in Knoten über this stack exchange funktionieren sollte, aber ich bin mir nicht sicher, was Pass tut, wenn es die Authentifizierung fehlschlägt. Ich habe folgendes LocalStrategy:Express Passport (node.js) Fehlerbehandlung

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); 
    }); 
    } 
)); 

Nachdem ich 'Error> einige err' Konsole Ausdruck sehen, sonst nichts passiert. Ich würde denken, dass es auf dem nächsten Pfad mit einem Fehlerparameter fortgesetzt werden sollte, aber das scheint das nicht zu tun. Was ist los?

Antwort

135

Die Strategie-Implementierung funktioniert in Verbindung mit passport.authenticate sowohl zum Authentifizieren einer Anfrage als auch zum Behandeln von Erfolg/Misserfolg.

Sagen Sie diesen Weg zu verwenden (die eine E-Mail-Adresse und ein Passwort übergeben wird):

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

Dies wird den Code in der Strategie nennen, wo eine von drei Bedingungen passieren kann:

  1. Beim Abrufen der Benutzerinformationen ist ein interner Fehler aufgetreten (z. B. die Datenbankverbindung ist verschwunden); Dieser Fehler würde weitergegeben werden: next(err); Dies wird von Express verarbeitet und generiert eine HTTP 500-Antwort.
  2. Die angegebenen Anmeldeinformationen sind ungültig (es gibt keinen Benutzer mit der angegebenen E-Mail-Adresse oder das Kennwort stimmt nicht überein); In diesem Fall generieren Sie keinen Fehler, aber Sie übergeben eine false als Benutzerobjekt: next(null, false); Dies löst die failureRedirect aus (wenn Sie keine definieren, wird eine nicht autorisierte HTTP 401-Antwort generiert);
  3. Alles auscheckt, Sie haben ein gültiges Benutzerobjekt, so dass Sie es weitergeben: next(null, user); Dies wird die successRedirect auslösen;

Bei einer ungültigen Authentifizierung (aber nicht ein interner Fehler), können Sie eine zusätzliche Nachricht zusammen mit dem Rückruf übergeben:

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

Wenn Sie verwendet haben failureFlashund installiert the connect-flash middleware, die Die mitgelieferte Nachricht wird in der Sitzung gespeichert und kann leicht abgerufen werden, um beispielsweise in einer Vorlage verwendet zu werden.

EDIT: es ist auch möglich, vollständig das Ergebnis des Prozesses selbst Authentifizierung zu umgehen (anstelle von Passport eine Umleitung oder 401 senden):

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); 
}); 
+2

Dank! Ich vermute, in meinem Fall versuche ich eine fehlgeschlagene Antwort über Ajax zu senden, anstatt eine Weiterleitung zu machen.Wenn ich mir die Passdokumente anschaue, denke ich, dass ich meine Route stattdessen mit einem benutzerdefinierten Funktionsrückruf formatieren muss. –

+3

Wenn es hilft, habe ich meine Antwort bearbeitet, um eine mögliche Art der Authentifizierung selbst zu zeigen :) – robertklep

+1

Danke für die Bearbeitung der "Authentifizierung selbst", das war ein Lebensretter! – wulftone

2

Sie müssen req.logIn(function (err) { }); hinzuzufügen und den Erfolg zu tun umleiten innen die Callback-Funktion

+0

Können Sie bitte Ihre Antwort klären? – dgilperez

15

Was Christian sagte, war Sie die Funktion

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

So ist die ganze Strecke wäre:

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); 
}); 

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