wake-up-neo.com

Nodejs und PassportJs: Umleitung der Middleware nach passport.authenticate wird nicht aufgerufen, wenn die Authentifizierung fehlschlägt

Ich habe keine Anmeldeseite, aber ich habe ein Anmeldeformular, das auf jeder Seite angezeigt wird. Ich möchte den Benutzer auf dieselbe Seite zurückleiten, auf der er sich befand, unabhängig davon, ob die Authentifizierung erfolgreich war (mit entsprechenden Flash-Nachrichten).

Nimm den folgenden Code:

app.post('/login', validateLogin, passport.authenticate('local-login'), function(req, res) {

    var redirectUrl = '/'; 

    if(req.body.to.length > 0){
        redirectUrl = req.body.to;  
    }

    console.log("THIS IS ONLY CALLED IF passport.authenticate() IS SUCCESSFUL");
    res.redirect(redirectUrl);
});

Ich sehe nur die letzte Middleware, die aufgerufen wird, wenn die Authentifizierung bestanden wird. Wenn dies fehlschlägt, wird der Pass scheinbar zu/login in Form einer Get-Anfrage umgeleitet. In meiner App existiert diese Seite nicht.

Wenn ich in der Passport-Authentifizierungsfunktion ein zusätzliches Optionsobjekt als Parameter übergeben habe, funktioniert dies:

app.post('/login', validateLogin, passport.authenticate('local-login', {

successRedirect : '/', // redirect to the secure profile section
    failureRedirect : '/signup', // redirect back to the signup page. THIS IS JUST FOR TESTING TO SEE IF THE REDIRECT ON FAIL WORKS.
    failureFlash : true, // allow flash messages

}


));

Dabei verliere ich jedoch die Möglichkeit zu wählen, wohin der Benutzer umgeleitet werden soll. Es scheint, dass der Pass die Kontrolle darüber übernimmt, wohin der Benutzer weitergeleitet wird, falls die Authentifizierung fehlschlägt. Wie kann ich das beheben? Oder ist es ein Fehler? Muss die Passport-Authentifizierung die letzte Middleware in der Kette sein, wenn die Authentifizierung fehlschlägt?

Dies ist mein lokaler Strategiefunktionsaufruf:

//LOCAL LOGIN

passport.use('local-login', new LocalStrategy({ 
    // by default, local strategy uses username and password, we will override with email
    usernameField : 'email',
    passwordField : 'password',
    passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form


    console.log("IN PASSPORT");

   if(email.length == 0 || password.length == 0){

       console.log("FIELDS ARE EMPTY"); 
      return done(null, false, req.flash('loginMessage', 'Fill in all values.'));

   }

    // find a user whose email is the same as the forms email
    // we are checking to see if the user trying to login already exists
    User.findOne({ 'local.email' :  email }, function(err, user) {
        // if there are any errors, return the error before anything else



        if (err){
            return done(err);
        console.log("db err");
        }
        // if no user is found, return the message
        if (!user){
            console.log("not user");
            return done(null, false, req.flash('loginMessage', 'Incorrect details.')); // req.flash is the way to set flashdata using connect-flash
        }    
        // if the user is found but the password is wrong

        if (!user.validPassword(password)){
            console.log("invalid pw");
            return done(null, false, req.flash('loginMessage', 'Incorrect details.')); // create the loginMessage and save it to session as flashdata
        }    
        // all is well, return successful user
        console.log("All OK");
        return done(null, user);
    });

}));
13
Paulie

Sie könnten einen benutzerdefinierten Authentifizierungsrückruf verwenden, wie im letzten Absatz beschrieben http://passportjs.org/guide/authenticate/ .

app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err); }
    // Redirect if it fails
    if (!user) { return res.redirect('/login'); }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      // Redirect if it succeeds
      return res.redirect('/users/' + user.username);
    });
  })(req, res, next);
});
30
ploutch

Ich bin auf die gleiche Ausgabe gestoßen, in der die Weiterleitungen anrufen, die auf erfolgreiche Facebook-Authentifizierung folgen

  • passport.authenticate ('facebook', ..) 

.. wurden nicht geehrt.

Basierend auf 'local' passportJS Strategy - und einer schönen Erinnerung an die Antwort von @ploutch hier .. Ich erkannte, dass der Schlüssel für die Umsetzung in dieser Aufforderung zu liegen scheint:

req.logIn(user, function(err) {
 ...
}

Für Facebook funktionierte dieser Routenaufbau für mich:

app.get(
        '/auth/facebook/callback',

        passport.authenticate
        (
            'facebook', 
            { failureRedirect: '/fbFailed' }
        ),

        function(req, res) 
        {
            var user = myGetUserFunc(); // Get user object from DB or etc

            req.logIn(user, function(err) {

              if (err) { 
                req.flash('error', 'SOMETHING BAD HAPPEND');
                return res.redirect('/login');
              }

              req.session.user = user;

              // Redirect if it succeeds
              req.flash('success', 'Fb Auth successful');
              return res.redirect('/user/home');
            });      
        }
); 
3
Gene Bo

Vollständige Antwort, einschließlich:

  • Middleware zur Einstellung von redirectUrl
  • Flash-Nachrichten
  • Es werden keine Werte zurückgegeben, die nicht verwendet werden

Erstellen Sie einfach einen redirectTo-Wert in Ihrer loginRequired-Middleware:

var loginRequired = function(req, res, next) {
    if ( req.isAuthenticated() ) {
        next();
        return
    }
    // Redirect here if logged in successfully
    req.session.redirectTo = req.path;
    res.redirect('/login')
}

Und dann in deinem Login POST:

router.post('/login', function(req, res, next) {
    passport.authenticate('local', function(err, user, info) {
        if ( err ) {
            next(err);
            return
        }
        // User does not exist
        if ( ! user ) {
            req.flash('error', 'Invalid email or password');
            res.redirect('/login');
            return
        }
        req.logIn(user, function(err) {
            // Invalid password
            if ( err ) {
                req.flash('error', 'Invalid email or password');
                next(err);
                return
            }
            res.redirect(req.session.redirectTo || '/orders');
            return
        });
    })(req, res, next);
});
0
mikemaccana