我創建了一個帶護照的簡單身份驗證應用程序(請參閱下面的代碼)。通過會話中間件進行表達,爲請求客戶端沒有會話的每個請求創建一個會話。我想只在登錄後分配會話或創建新會話後分配會話。使用Passport進行身份驗證後創建新會話
這是因爲我最終會做了HTTPS登錄,並想阻止黑客從已通過驗證的用戶劫持會話。
這裏是我的服務器代碼:
// Server.js configures the application and sets up the webserver
//importing our modules
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var MongoStore = require('connect-mongo')(express);
var configDB = require('./config/database.js');
//Configuration of Databse and App
mongoose.connect(configDB.url); //connect to our database
require('./config/passport')(passport); //pass passport for configuration
app.configure(function() {
//set up our express application
app.use(express.logger('dev')); //log every request to the console
app.use(express.cookieParser()); //read cookies (needed for auth)
app.use(express.bodyParser()); //get info from html forms
app.set('view engine', 'ejs'); //set up ejs for templating
//configuration for passport
app.use(express.session({ secret: 'olhosvermdfgytuelhoseasenhaclassica',
cookie: {
maxAge: 120000 },
store:
new MongoStore({
db: 'xYrotr4h',
host: 'novus.modulusmongo.net',
port: 27017,
username: 'gdog',
password: 'fakepassowrd123'
})
})); //session secret + expiration + store
app.use(passport.initialize());
app.use(passport.session()); //persistent login session
app.use(flash()); //use connect-flash for flash messages stored in session
});
//Set up routes
require('./app/routes.js')(app, passport);
//launch
app.listen(port);
console.log("Server listening on port" + port);
在我的新護照的本地策略,我試圖用req.session.regenerate()或req.session.reload()當用戶成功驗證反對數據庫但導致服務器崩潰。
這是我如何定義我的策略:
//Passport.js sets up our local strategies
//imports
var LocalStrategy = require('passport-local').Strategy;
var User = require('../app/models/user');
//export this as a module since we give it to passport
module.exports = function(passport) {
//Set up the session for persistent login
passport.serializeUser(function(user, done) {
done(null, user.id);
});
//used to serialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
//setting up local sign up
passport.use('local-signup', new LocalStrategy({
//by default, the local strategy uses usernames and password, we will override with email
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
function(req, email, password, done) {
console.log("Callback ran!");
//asynchronous
//User.findOne wont fire unless data is sent back
process.nextTick(function() {
console.log("I did run!");
//find user whose email is the same as form email
// we are checking to see if the user trying to sign up already exists
User.findOne({ 'local.email': email }, function(err, user) {
//if there any errors, return the errors
if (err) {
return done(err);
}
//check to see if there any users already with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
console.log('New user will be added to the DB!');
//if there is no user with that e-mail, create the user
var newUser = new User();
//we set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
//save the user in the store
newUser.save(function(err) {
if (err) {
throw err;
}
return done(null, newUser);
});
}
});
});
}));
// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// 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-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
// 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);
// if no user is found, return the message
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.')); // 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))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
// removing the req.session.regenerate fixes any crashing
req.session.regenerate(function(err, done, user){
return done(null, user);
});
});
}));
};
如果黑客可以從用戶劫持會話,他們就不能劫持所生成的新會話? – bnuhero
我相信他們至少很難區分經過身份驗證和未經身份驗證的會話。經過身份驗證的會話將通過HTTPS進行。 –