Store sessions in mongodb with connect-mongo and mongoose

lumberjacked picture lumberjacked · Nov 6, 2013 · Viewed 8.5k times · Source

I am getting errors left and right while I try to configure the express.js session storage with mongodb. I am using locomotive for my framework and have configured mongoose.

In my initializers directory for 02_mongoose.js I have this.

module.exports = function() {
    mongoose.connect('mongodb://localhost:27018/basbac');
    mongoose.model('User', UserSchema);
}

I know I have a connection to the database because I can pull my users in my controller.

DeveloperController.show = function() {

var self = this;
var user = mongoose.model('User');

user.find().exec(function(error, users) {

    if(error) {
        console.log(error);
    } else {
        self.res.json({response: { id: self.param('id'), api: self.param('api'), users: users } });    
    }

});

}

http://localhost:3000/developer/test/?api=hhfkgjhukdsfkjhvsduhvudhcsiudvlskejfbk

{
  response: {
  id: "test",
  api: "hhfkgjhukdsfkjhvsduhvudhcsiudvlskejfbk",
  users: [
    {
      _id: "52706695a43c83a739358de5",
      firstname: "cad",
      lastname: "bane",
      address: "duro",
      email: "[email protected]"
    },
    {
      _id: "52706695a43c83a739358de6",
      firstname: "jar jar",
      lastname: "binks",
      address: "naboo",
      email: "[email protected]"
    }
   ]
   }
}

Inside my config/all.js I have this as my configuration for sessions

var MongoStore = require('connect-mongo')(express);
var mongoose = require('mongoose');

this.use(express.cookieParser());

this.use(express.session({ 
    secret: 'keyboard cat',
    store: new MongoStore({
        mongoose_connection: mongoose.connection
    }) 
}));

But this throws an error.

this.db = new mongo.Db(options.mongoose_connection.db.databaseName,
TypeError: Cannot read property 'databaseName' of undefined

I also tried to do it like the connect-mongo docs where saying but I get an error with that as well. (https://github.com/kcbanner/connect-mongo) mongoose_connection in the form: someMongooseDb.connections[0] to use an existing mongoose connection. (optional)

this.use(express.session({ 
    secret: 'keyboard cat',
    store: new MongoStore({
        mongoose_connection: mongoose.connections[0]
    }) 
}));

But I get the same error as before.

this.db = new mongo.Db(options.mongoose_connection.db.databaseName,
TypeError: Cannot read property 'databaseName' of undefined

I also tried to do as many articles are saying to do. Here is one for example of someones working configuration (Logout in ExpressJS, PassportJS and MongoStore)

this.use(express.session({ 
    secret: 'keyboard cat',
    store: new MongoStore({
        db: mongoose.connection.db
    }) 
}));

But that also produces an error, and I know that the db key is actually undefined

throw new Error('Required MongoStore option `db` missing');

What am I doing wrong to pass this connection into the new MongoStore? When I start console.log() the mongoose object I am not able to find any information about the connection it is using. I do see a base object but it does not have a db key inside it. Do I need to pass some more options into the mongoose configuration?

Answer

robertklep picture robertklep · Nov 6, 2013

The problem is the order in which Locomotive starts up. According to the docs:

When a Locomotive application is started, it proceeds through a sequence of steps:

Configure the Environment

In this step, config/environments/all.js is executed followed by the configuration file for the current environment. For instance, when running in development, config/environments/development.js is executed.

Invoke Initializers

After the environment has been configured, initializers are invoked. Initializers are used to configure sub-systems and connect to databases, message queues, and other services utilized by the application.

So when your environment code is being called, the initializer hasn't yet run and Mongoose isn't configured. Try moving the Mongoose setup to a separate file (I use app/db/mongoose myself, but that's a matter of personal preference) and require that in your environment file.