I have a Node server set up with Express, using Passport for authentication. I've heard that connect-mongo is good to use for persistent login sessions, so I have it set up and everything seems to work fine at first, with user sessions being automatically deleted by mongo according to the expire time. However, in production, for every user session there are 5000 other empty sessions that never expire, and I can't figure out why mongo doesn't automatically clean those up. An example entry of the empty session in mongo looks like this:
{ "_id" : "JMtV5Z1oWRkgh9KIKlwSqwOE",
"session" : "{\"cookie\":{\"originalMaxAge\":86400000,\"expires\":\"2014-02-13T22:09:09.948Z\",\"httpOnly\":true,\"path\":\"/\"},\"passport\":{}}",
"expires" : Date( 1392329349948 ) }
Here is the Express configure code:
var express = require('express')
, passport = require('passport')
, fs = require('fs')
, http = require('http')
, https = require('https')
, util = require('util')
, mongoose = require('mongoose')
, MongoStore = require('connect-mongo')(express)
, FacebookStrategy = require('passport-facebook').Strategy
, LocalStrategy = require('passport-local').Strategy;
app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.logger());
app.use(requireHTTPS);
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({
secret: 'asdfasdf',
cookie: { maxAge: 24 * 60 * 60 * 1000 },
store: new MongoStore({
mongoose_connection: mongoose.connections[0],
clear_interval: 3600
}, function(err){
console.log(err || 'connect-mongodb setup ok');
}
)
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(__dirname + '/public'), { maxAge: 31557600000 });
});
I'm thinking these empty sessions are being created from search bots, because I can't think of any other reason why my site would be hit 20,000 times in one night. But even so, as long as the sessions expire correctly it wouldn't be a problem and my database wouldn't run out of memory, but they never get cleaned up.
Any insight would be appreciated, thanks
connect-mongo appears to be working correctly. You're setting maxAge to 1000 days, and that's what is getting stored in the cookie. See ttl info here.
I suspect your issue is that you actually only want cookies issued when the user logs in, not for every request of any asset (page, image, Javascript, etc.). In that case, you can add an optional first parameter in front of express.cookieParser and express.session so that that middleware only runs on certain paths (e.g., /login).
Alternatively, you can move your express.static middleware above express.cookieParser and then no cookies will be issued for static assets.
Read the documentation here
Removing expired sessions
connect-mongo uses MongoDB's TTL collection feature (2.2+) to have mongod automatically remove expired sessions. (mongod runs this check every minute.)
Note: By connect/express's default, session cookies are set to expire when the user closes their browser (maxAge: null). In accordance with standard industry practices, connect-mongo will set these sessions to expire two weeks from their last 'set'. You can override this behavior by manually setting the maxAge for your cookies -- just keep in mind that any value less than 60 seconds is pointless, as mongod will only delete expired documents in a TTL collection every minute.
For more information, consult connect's session documentation
cookie: { maxAge: 24 * 60 * 60 * 1000 }
You are setting a cookie expiry time of 1000 days, hence the sessions are not getting expired. You can set it to a lower value like a day or two.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With