如果Passport身份validation失败,如何在redirect时保留表单数据?

我正在尝试使用护照在网页上对用户进行身份validation。 一切正常,除非身份validation失败,并且护照将用户redirect到同一个路由,则表单上的所有数据都将丢失。 有没有一种方法来保存数据并将其传回给表单。

我在routes.js中有以下内容

// ===================================== // SIGNUP ============================== // ===================================== // show the signup form app.get('/signup', function(req, res) { // render the page and pass in any flash data if it exists signup.isAuthenticated = req.isAuthenticated(); signup.user = req.user; signup.message = req.flash('signupMessage'); res.render('signup', signup); }); // process the signup form app.post('/signup', passport.authenticate('local-signup', { successRedirect : '/', // redirect to the secure section failureRedirect : '/signup', // redirect back to the signup page if there is an error failureFlash : true // allow flash messages })); 

在我的passport.js我有以下几点:

 // ========================================================================= // LOCAL SIGNUP ============================================================ // ========================================================================= // we are using named strategies since we have one for login and one for signup // by default, if there was no name, it would just be called 'local' passport.use('local-signup', 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 }, // this function is used when signing up function(req, email, password, done) { // TODO: get the user from data if(email == 'myemail@gmail.com') { // user email already exists console.log('user already exists !'); return done(null, false, req.flash('signupMessage', 'That email is already taken.')); } else { // if there is no user with that email // create the user var newUser = { username : 'myemail@gmail.com', name : 'Name Surname' }; newUser.local.email = email; newUser.local.password = newUser.generateHash(password); return done(null, newUser); } })); 

和我的server.js有以下几点:

 // server.js // set up ====================================================================== // get all the tools we need var express = require('express'); var path = require('path'); var app = express(); var port = process.env.PORT || 3000; // var mongoose = require('mongoose'); var passport = require('passport'); var flash = require('connect-flash'); var morgan = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var session = require('express-session'); var multer = require('multer'); var configDB = require('./config/database.js'); // configuration =============================================================== // mongoose.connect(configDB.url); // connect to our database require('./config/passport')(passport); // pass passport for configuration // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); // set up our express application app.use(morgan('dev')); // log every request to the console app.use(bodyParser.json()); // get information from html forms app.use(bodyParser.urlencoded({ extended: false })); // use multer to process multi-part requests and multer to save our files by default to /uploads/ directory app.use(multer({ dest : path.join(__dirname, '/uploads/'), limits : { fieldNameSize : 200, // 200 bytes files : 5, // 5 files fileSize : 5194304000000, // 5 GB fields : 50 // 50 fields on the form } })) app.use(cookieParser()); // read cookies (needed for auth) app.use(express.static(path.join(__dirname, 'public'))); // required for passport app.use(session({ secret: 'mylongsecretpassphrase', resave : true, saveUninitialized : true })); // session secret app.use(passport.initialize()); app.use(passport.session()); // persistent login sessions app.use(flash()); // use connect-flash for flash messages stored in session // routes ====================================================================== require('./app/routes.js')(app, passport); // load our routes and pass in our app and fully configured passport // show error page if the resource is not found app.use('*', function(req, res) { res.render('page-error', { title : 'myWeb - Page Error', description : 'my web page', keywords : 'keywords1, keywords2, keywords3' }); }); // launch ====================================================================== app.listen(port); console.log('Node listens on port ' + port); 

任何帮助将不胜感激 !

如果您不想丢失表单数据,则可以使用AJAX发送表单,并在身份validation失败的情况下发送401未授权的状态。 护照在默认情况下发送401,所以以下应该工作(未经testing,可能包含错别字):

 app.post('/login', function(req, res, next) { passport.authenticate('local-signup', function(req, res) { // If this function gets called, authentication was successful. If not, your ajax call gets a 401 status and you can handle it in .fail() res.redirect('/'); }); }); 

护照网站的一些解释:

默认情况下,如果身份validation失败,Passport将以401 Unauthorized状态响应,并且不会调用任何其他路由处理程序。 如果authentication成功,则将调用下一个处理程序,并将req.user属性设置为已通过身份validation的用户。

而不是像使用默认的callback

 passport.authenticate('local-signup', { successRedirect : '/', // redirect to the secure section failureRedirect : '/signup', // redirect back to the signup page if there is an error failureFlash : true // allow flash messages }) 

你可以使用一个自定义的callback ,并通过像这样的flash消息传递任何你想要的inputvariables

 router.post('/signup', function(request, response, next) { passport.authenticate('local-signup', function(err, user, info) { if (err) return next(err); if (!user) { // Attach flash messages to keep user input request.flash('emailInput', request.body.email); request.flash('usernameInput', request.body.username); return response.redirect('/signup'); } // 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. request.logIn(user, function(err) { if (err) return next(err); return response.redirect('/profile'); }); })(request, response, next); }); 

那么当redirect的时候,你可以像往常一样发送Flash消息到你的视图模板

 response.render('signup.ejs', { signupMessage: request.flash('signupMessage'), emailInput: request.flash('emailInput'), usernameInput: request.flash('usernameInput') });