Nodejs和PassportJs:在passport之后redirect中间件。如果authentication失败,authentication不被调用

我没有login页面,而是我有一个login表单出现在每一页上。 我想将用户redirect到他们所在的同一页面,无论身份validation是否成功(使用适当的Flash消息)

采取以下代码:

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

如果authentication通过,我只能看到上面最后被调用的中间件。 如果失败,那么护照似乎是以get请求的forms将我redirect到/ login。 在我的应用程序这个页面不存在。

如果我传递一个额外的选项对象作为参数在护照validationfunction,那么这个工程:

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

但在这样做,我失去了select在哪里redirect用户的能力。 看来如果authentication失败,护照将控制用户redirect到哪里。 我怎样才能解决这个问题? 或者是一个错误? 如果身份validation失败,必须通过身份validation才能成为链中的最后一个中间件?

这是我的本地策略函数调用:

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

       

网上收集的解决方案 "Nodejs和PassportJs:在passport之后redirect中间件。如果authentication失败,authentication不被调用"

您可以使用自定义身份validationcallback,如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); }); 

我遇到了同样的问题,其中redirect的电话,成功Facebookvalidation后

  • passport.authenticate('脸谱',..)

..没有被尊重。

基于“本地”passportJS策略 – 以及从@ ploutch的答案这里很好的提醒..我意识到让它的工作似乎在这个呼吁的关键:

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

对于Facebook,这个路线设置为我工作:

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

完整答案,包括:

  • 中间件来设置redirectUrl
  • Flash消息
  • 没有返回不会被使用的值

只需在您的loginRequired中间件中创build一个redirectTo值:

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

然后在你的loginPOST:

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