6

I am currently having a hell of time trying to store sessions in MongoDb.

I've tried express-session-mongo and connect-mongodb and both give me the same "500 internal server error" when I try to load the login page. Which leads me to think maybe there is a conflict with mongoose-auth somewhere.

Anyway here is my setup:

app.js:

var MongoStore = require('connect-mongodb');
var MongoDb = require('mongodb').Db;
var Server = require('mongodb').Server;

var db = new MongoDb('myDb', new Server('localhost', 27017, {auto_reconnect: true, native_parser: false}));

app.configure(function() {
  app.use(express.logger({format: 'dev'}));
  app.set('views', __dirname + '/../views');
  app.set('view engine', 'jade');
  app.set('view options', { layout: false });
  app.use(express.bodyParser());
  app.use(express.cookieParser());
  app.use(mongooseAuth.middleware());
  app.use(require('./mysite').middleware());
  app.use(express.methodOverride());
});


app.configure('production', function(){
  var oneWeek = 657450000;
  app.use(express.static(__dirname + '/../public', { maxAge: oneWeek }));
  app.use(express.session({ store: new MongoStore({db: db}), secret: 'super secret' }));
  app.use(express.errorHandler());
});

// Routes
require('./routing.js');

mongooseAuth.helpExpress(app);

app.listen(3000);
console.log('Express server listening on port %d in %s mode', app.address().port, app.settings.env);

userModel.js

var Schema = mongoose.Schema;
var mongooseTypes = require("mongoose-types");
var mongooseAuth = require('mongoose-auth');
mongooseTypes.loadTypes(mongoose);

var everyauth = require('everyauth')
everyauth.debug = true;

var UserSchema = new Schema({any: {}});

UserSchema.plugin(mongooseAuth, {
    everymodule: {
      everyauth: {
          User: function () {
            return User;
          }
      }
    }
    , password: {
      loginWith: 'email'
      , extraParams: {
            phone: String
          , username: String
        }
      , everyauth: {
            getLoginPath: '/login'
          , postLoginPath: '/login'
          , loginView: 'account/login.jade'
          , getRegisterPath: '/register'
          , postRegisterPath: '/register'
          , registerView: 'account/register.jade'
          , loginSuccessRedirect: '/login/success'
          , registerSuccessRedirect: '/register/success'
        }
    }
});

mongoose.model('User', UserSchema);
User = mongoose.model('User');

At this moment in time I'm really just trying to use MongoDb as the session store, but again I get a 500 error w/ no information whatsoever in the node.js console when I try to load the login page.

Any help would be greatly appreciated.

Thanks

Lancelot
  • 2,417
  • 12
  • 39
  • 46
  • Actually I just retried with express-session-mongo and although I'm still getting the same behavior (trying to load the login page fails w/ a 500 error), I just checked in MongoDb and the session is actually there as expected. – Lancelot Mar 01 '12 at 22:46
  • FYI, also did try connect-mongo, same result... mongoose-auth not playing nice? – Lancelot Mar 01 '12 at 23:18
  • After some digging into the everyauth module's code, all I was able to figure out was that the 500 error happened in everyauth/lib/modules/password.js >> line 47: res.render(view, locals); Unfortunately that doesn't help too much from where I stand... :( – Lancelot Mar 02 '12 at 17:42

2 Answers2

10

It ended being a problem of the various modules: connect-session-mongo / express-session-mongo / connect-mongo, using connect 2.0.1 and Express using connect 1.8.5.

Apparently the dependency clash here prevented the session store modules to access the 'req.secret' property.

To make it work I ended using the module connect-mongodb that is still using connect 1.8.5, just like Express.

The reason I couldn't make connect-mongodb work before though was user error, I tried too hard to use copy/paste from online examples instead of my head.

Here is the configuration code that ended up working for me with connect-mongodb:

var Session = require('connect-mongodb');

app.configure('production', function(){
  var oneWeek = 657450000;
  app.use(express.static(__dirname + '/../public', { maxAge: oneWeek }));

  var session = express.session({
        store: new Session({
              url: 'mongodb://localhost:27017/test', 
              maxAge: 300000
        }),
        secret: 'superTopSecret' 
  });
  app.use(session);

  app.use(mongooseAuth.middleware());
  app.use(require('./mySite').middleware());
  app.use(express.methodOverride());
  app.use(express.errorHandler());  
});

Hope this helps anyone else who runs into this issue. If you have any suggestion/improvement on this solution, I'd be glad to hear it. :)

Yasin Okumuş
  • 2,299
  • 7
  • 31
  • 62
Lancelot
  • 2,417
  • 12
  • 39
  • 46
  • 3
    Thanks for this, helped me out. I was also able to use Mongoose's existing connection instead of specifying the URL. Which is especially nice when you have multiple environments with separate DB instances. Just replace the `url` param with: `db: mongoose.connection.db` – k00k Jun 11 '12 at 16:42
  • I just want to say, you're great. – Lazy Sep 06 '14 at 17:55
1
const express = require('express')
const app = express()
const cookieParser = require('cookie-parser');
const session = require('express-session')
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo')(session);

mongoose.connect('mongodb://localhost/my-database', {
    useMongoClient: true
});
mongoose.Promise = global.Promise;
const db = mongoose.connection

app.use(cookieParser());
app.use(session({
    secret: 'my-secret',
    resave: false,
    saveUninitialized: true,
    store: new MongoStore({ mongooseConnection: db })
}));
R_V
  • 11
  • 1
  • 3
    While this might answer the question, if possible you should [edit] your answer to include a short explanation of *how* this code block answers the question. This helps to provide context and makes your answer much more useful to future readers. – Hoppeduppeanut Mar 23 '21 at 03:27