I created a simple authentication application with a passport (see code below). Express through the session middleware creates a session for each request in which the requesting client does not have a session. I would like to assign sessions only after registering or creating a new session after logging in.
This is because I will ultimately log in via HTTPS and would like to prevent hackers from hijacking sessions from authenticated users.
Here is my server code:
// 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);
In my new local Passport strategy, I tried using req.session.regenerate () or req.session.reload () when the user was successfully verified against the database, but this caused the server to crash.
Here is how I define my strategy:
//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 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); }); }); })); };