【发布时间】:2019-09-05 19:28:19
【问题描述】:
我创建了一个带有护照的简单身份验证应用程序(请参见下面的代码)。通过会话中间件表达,在请求客户端还没有会话的每个请求上创建一个会话。我只想在登录后分配会话或在登录后创建新会话。
这是因为我最终将通过 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);
在我的新 Passport 本地策略中,当用户成功通过数据库验证但导致服务器崩溃时,我尝试使用 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);
});
});
}));
};
【问题讨论】:
-
如果黑客可以劫持用户的会话,他们就不能劫持新生成的会话吗?
-
我相信他们至少会很难区分经过身份验证的会话和未经身份验证的会话。并且经过身份验证的会话将通过 HTTPS。
标签: node.js session authentication passport.js