Search code examples
node.jsmongodbsessionexpressmonk

Trouble with MongoDB / Monk / Express-Sessions setup ("cannot serialize user")


I'm trying to set up my first Mongo authentication system and it goes pretty well up until the point where I try to create a session for the user with express-sessions.

My user routes are fine -- I can register and login, and it's reflected in the database -- but once I get to the step of creating the session, I get the "Failed to serialize user into session" error.

I suspect the error is in the way I've set up my sessions:

//var MongoStore = require('connect-mongostore')(session);
app.use(session({
   //store: new MongoStore({ db: 'callcongress', url: 'mongodb://localhost:27017/callcongress', collections: ['usercollection', 'sessions']}),
  secret: process.env.SECRET_KEY,
  resave: false,
  saveUninitialized: true,
}));

The store and MongoStore lines are commented out at the moment.... having them in makes the following happen (changes as I refresh the page):

  • Server hangs and doesn't respond
  • Error getting collection: sessions <Error: Error setting TTL index on collection : sessions <Error: Error setting TTL index on collection : sessions <Error: Cannot determine state of server>>>
  • Cannot determine state of server (I tried looking up this error but all the other questions that had it were about heroku deployments?)

I have tried the MongoStore with a bunch of different sets of options, all of which had the same result.

Here is what happens in the terminal when I log in (the result of a console of console.logs):

{ _id: 58ab42c1f0a05388ce3b2348,
  username: 'test16',
  name: 'test',
  password: '$2a$10$i6sip04Jw6ylk83aOfnXIui7dszBIbe0OEdLSNVsRHQe8Xquy1r7O',
  email: 'test@test.com',
  district: 'New York 5th' }
got it
POST /auth/login 500 115.327 ms - 1003

And here's what my serialize/deserialize methods look like:

const passport = require('passport');


var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/callcongress');
const userCollection = db.get('usercollection');

module.exports = () => {
  var user_cache = {};
  passport.serializeUser(function(user, next) {
    console.log('in serialize');
    let id = user._id;
    user_cache[id] = user;
    done(null, id);
  });

  passport.deserializeUser((id, done) => {
    console.log('in deserialize 1');
    userCollection.findById(id)
      .then((user) => {done(null, user_cache[id]);})
      .catch((err) => {done(err, null);});
  });
};

None of the console.logs in here output anything, which also sort of mystifies me. The one at the end of my local strategy does work, though.

I've looked into Mongoose some and would rather not use it at this point -- I'm struggling with the concept of MongoDB enough without adding another thing into the mix. Any insight would be appreciated.


Solution

  • Looks like user serialization in express sessions doesn't work without a model. I ended up using Mongoose.