2014-10-11 35 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') 
});