Question

I'm trying to store the sessions of my Express app in a MongoStore but I get an error at the connection. The error is a huge Object/JSON that I couldn't make sense of, so I tried every alternatives I found online but no luck so far...

Here is the app configuration:

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

var app = express();

app.configure(function(){
    app.use(express.compress());
    app.use(express.static(path.join(__dirname, 'public')));
    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs');
    app.set('port', process.env.PORT || 8000);
    app.use(express.favicon(__dirname + '/public/img/favicon.ico'));
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser('secret'));
    app.use(express.session({
            secret: 'secret',
            store: new MongoStore({
                    db: dbOptions.db,
                    host: dbOptions.host,
                    port: dbOptions.port,
                    username: dbOptions.username,
                    password: dbOptions.password
            },
            function(err){
                    console.log(err || 'connect-mongodb setup ok');
            })
    }));
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
});

app.configure('development', function(){
    app.use(express.errorHandler());
});

And this is the error that is being logged in the console:

{ db:
   { domain: null,
     _events: {},
     _maxListeners: 10,
     databaseName: 'dbname',
     serverConfig:
      { domain: null,
        _events: {},
        _maxListeners: 10,
        _callBackStore: [Object],
        _commandsStore: [Object],
        auth: [Object],
        _dbStore: [Object],
        host: 'ec2-xx-xxx-xxx-xx.eu-west-1.compute.amazonaws.com',
        port: 27017,
        options: [Object],
        internalMaster: true,
        connected: true,
        poolSize: 5,
        disableDriverBSONSizeCheck: false,
        _used: true,
        replicasetInstance: null,
        emitOpen: false,
        ssl: false,
        sslValidate: false,
        sslCA: null,
        sslCert: undefined,
        sslKey: undefined,
        sslPass: undefined,
        serverCapabilities: [Object],
        name: 'ec2-xx-xx-xxx-xx.eu-west-1.compute.amazonaws.com:27017',
        _readPreference: null,
        socketOptions: [Object],
        logger: [Object],
        eventHandlers: [Object],
        _serverState: 'connected',
        _state: [Object],
        recordQueryStats: false,
        socketTimeoutMS: [Getter/Setter],
        db: [Circular],
        dbInstances: [Object],
        connectionPool: [Object],
        isMasterDoc: [Object] },
     options: { w: 1 },
     _applicationClosed: false,
     slaveOk: false,
     bufferMaxEntries: -1,
     native_parser: undefined,
     bsonLib:
      { Code: [Function: Code],
        Symbol: [Function: Symbol],
        BSON: [Object],
        DBRef: [Function: DBRef],
        Binary: [Object],
        ObjectID: [Object],
        Long: [Object],
        Timestamp: [Object],
        Double: [Function: Double],
        MinKey: [Function: MinKey],
        MaxKey: [Function: MaxKey],
        promoteLongs: true },
     bson: { promoteLongs: true },
     bson_deserializer:
      { Code: [Function: Code],
        Symbol: [Function: Symbol],
        BSON: [Object],
        DBRef: [Function: DBRef],
        Binary: [Object],
        ObjectID: [Object],
        Long: [Object],
        Timestamp: [Object],
        Double: [Function: Double],
        MinKey: [Function: MinKey],
        MaxKey: [Function: MaxKey],
        promoteLongs: true },
     bson_serializer:
      { Code: [Function: Code],
        Symbol: [Function: Symbol],
        BSON: [Object],
        DBRef: [Function: DBRef],
        Binary: [Object],
        ObjectID: [Object],
        Long: [Object],
        Timestamp: [Object],
        Double: [Function: Double],
        MinKey: [Function: MinKey],
        MaxKey: [Function: MaxKey],
        promoteLongs: true },
     _state: 'connected',
     pkFactory:
      { [Function: ObjectID]
        index: 16051204,
        createPk: [Function: createPk],
        createFromTime: [Function: createFromTime],
        createFromHexString: [Function: createFromHexString] },
     forceServerObjectId: false,
     safe: false,
     notReplied: {},
     isInitializing: true,
     openCalled: true,
     commands: [],
     logger: { error: [Function], log: [Function], debug: [Function] },
     tag: 1387402758191,
     eventHandlers:
      { error: [],
        parseError: [],
        poolReady: [],
        message: [],
        close: [] },
     serializeFunctions: false,
     raw: false,
     recordQueryStats: false,
     retryMiliSeconds: 1000,
     numberOfRetries: 60,
     readPreference: undefined },
  collectionName: 'sessions',
  internalHint: null,
  opts: {},
  slaveOk: false,
  serializeFunctions: false,
  raw: false,
  readPreference: 'primary',
  pkFactory:
   { [Function: ObjectID]
     index: 16051204,
     createPk: [Function: createPk],
     createFromTime: [Function: createFromTime],
     createFromHexString: [Function: createFromHexString] },
  serverCapabilities: undefined }

It's pretty obscure so I have no idea in which direction I should search.

EDIT 1:

Ok thanks that makes more sense now but the thing is I tried to log an error because the sessions aren't stored in MongoDB and I don't understand why. I added a try catch block around the setup of the MongoStore to see if an error was triggered and there is none so I have no clue why it's not working...

This is how passportjs store and retrieve sessions:

passport.serializeUser(function(user, done) {
    done(null, user._id);
});

passport.deserializeUser(function(_id, done) {
    var userProvider = new UserProvider();
    userProvider.findUser({ _id: _id }, function (err, users) {
            if(users.length > 0) { done(null, users[0]); }
            else { done(err, null); }
    });
 });

What am I missing?

Thanks for your help!

Was it helpful?

Solution

Your problem is in the following line:

store: new MongoStore({
  db: dbOptions.db,
  host: dbOptions.host,
  port: dbOptions.port,
  username: dbOptions.username,
  password: dbOptions.password
},
function(err){
  console.log(err || 'connect-mongodb setup ok');
})

Simply remove the last function and I believe it should work as you initially expected

Contrary to Andrei's answer there, the MongoStore constructor does accept a callback. However it's not for error handling purposes - it actually passes back the collection property of MongoStore (which is why console.log spewed out what it did). If there's an error, MongoStore will simply throw an error. You can find it in the source code by clicking here. The callback is invoked on line 164.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top