2014-10-11 61 views
1

我正在尝试使用护照在网页上验证用户身份。一切正常,除非身份验证失败并且护照将用户重定向到同一个路由,则表单上的所有数据都将丢失。有没有办法来保存数据并将它们传递回表单。如果Passport身份验证失败,如何在重定向时保留表单数据?

我有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 == '[email protected]') { 
      // 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 : '[email protected]', 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); 

任何帮助将不胜感激!

+0

我看到在express中完成的一种方式是将数据存储在服务器端会话对象中,然后当重定向的请求进入时,您可以检查保存的数据是否在会话对象中,如果是,则您在页面投放时将其放入页面,然后清除会话中的数据。我认为connect-flash就是这样做的一个模块。您也可以将数据放入cookie中,尽管服务器端会话让您不必将其发送回客户端,然后让客户端在重定向过程中将其发送回服务器。 – jfriend00 2014-10-11 21:28:47

+1

你可以尝试通过ajax发送表单,所以如果认证失败,你不会更改页面。 – xShirase 2014-10-11 21:51:49

回答

2

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

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

的解释从Passport网站的资料:

默认情况下,如果验证失败,护照以未授权状态回复401 ,并且任何其他路由处理程序将不会被调用 。如果身份验证成功,则将调用下一个处理程序 ,并将req.user属性设置为已通过身份验证的用户。

+0

上面的代码实际上并不符合我的要求,但AJAX工作得很好。谢谢你的提示。 – fitims 2014-10-29 10:10:04

2

不使用默认的回调像

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

,你可以用一个custom callback,并通过乏任何你想要的输入通过提示信息,像这样

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

然后,重定向时,你可以发送闪光消息到你的视图模板像正常

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