I have my nodejs app hosted on Openshift. Here are my specs:
node v0.10.35, express v3.4.8
My package.json dependencies:
"dependencies": {
"angular-loading-bar": "^0.9.0",
"async": "^2.0.0-rc.5",
"bcrypt-nodejs": "0.0.3",
"body-parser": "~1.0.0",
"connect-flash": "^0.1.1",
"connect-mongo": "^1.2.0",
"cookie-parser": "~1.0.0",
"ejs": "^2.4.1",
"express": "~3.4.4",
"lodash": "^4.12.0",
"method-override": "~1.0.0",
"mongodb": "~2.x",
"mongoose": "~4.4.12",
"morgan": "~1.0.0",
"nodemailer": "^2.3.2",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"recaptcha2": "^1.0.8"
},
And here is my server.js
#!/bin/env node
var express = require('express');
var fs = require('fs');
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var MongoStore = require('connect-mongo/es5')(express);
var app = express();
var server_port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
var server_ip_address = process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0';
//MongoD
mongodb_connection_string = process.env.OPENSHIFT_MONGODB_DB_URL + "tenders";
mongoose.connect(mongodb_connection_string);
var dbconn = mongoose.connection;
dbconn.on('error', console.error.bind(console, 'connection error:'));
dbconn.once('open', function(){
console.log('Connected to Mongoose Database.');
});
// Close MongoD connection when app is terminated
process.on('SIGINT', function (){
mongoose.disconnect();
dbconn.close(function (){
console.log("Server halted: Mongoose default connection disconnected.");
process.exit(0);
});
});
/* Configuration */
app.set('view engine', 'ejs'); // set up ejs for templating
/* Middlewares */
app.use(express.static(__dirname + "/views"));
app.use(express.static(__dirname + "/public"));
// set up our express application
app.use(morgan('dev')); // log every request to the console
app.use(bodyParser()); // get information from html forms
app.use(cookieParser()); // read cookies (needed for auth)
/** Persistent database backed session **/
app.use(express.session({
secret: process.env.SECRET,
store: new MongoStore({mongooseConnection : mongoose.connection})
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
require('./routes/routes')(app, passport);
require('./config/passport')(passport); configuration
app.use(function(req, res) {
res.redirect('/')
});
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
res.status(401);
res.json({"message" : err.name + ": " + err.message});
}
});
/* Start server */
app.listen(server_port, server_ip_address, function(){
console.log("Listening on " + server_ip_address + ":" + server_port);
});
The problem is connect-mongo is creating a new session every second as I can see from counting the number of entries in sessions collection in my database. The sessions are being created even when there are no active users currently using the website. Is this normal ?
Edit : Is it due to the middleware I use to check if user is logged in using passport isauthenticated method for most of the api call. But the strange thing is its being called even when there are no users making requests to server as you can see from the node.log below that keeps redirecting
GET / 302 3ms - 40b
GET / 302 3ms - 40b
GET / 302 2ms - 40b
GET / 302 2ms - 40b
GET / 302 3ms - 40b
GET / 302 20ms - 40b
GET / 302 3ms - 40b
GET / 302 2ms - 40b
GET / 302 3ms - 40b
GET / 302 4ms - 40b
If you are using express-session >= 1.10.0 and don't want to resave all the session on database every single time that the user refresh the page, you can lazy update the session, by limiting a period of time. Because you're are using a newer version of connect-mongo and an older version of express im not 100% sure,but i think this is because of either the cookie or the Uninitialized session.
// Configuring sessions
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
app.use(session({
secret: 'JohnSecret',
saveUninitialized: false, // don't create session until something stored
resave: false, //don't save session if unmodified
store: new MongoStore({
url: 'mongodb://localhost/John',
autoRemove: 'interval',
autoRemoveInterval: 10 // In minutes. Default
})
}));
Okay, it is the issue with HAProxy continuously checking the backend server to see that its up and working. In doing so it is creating a session a second and cluttering my database. So here is my (dirty) fix:
Create an api
/ping
that handles HAProxy's httpchk by destroying each sessionapp.get('/ping', function(req, res){ req.session.destroy(); res.send(200); });
Configure
haproxy/conf
to changeoption httpchk GET /
tooption httpchk GET /ping
Restart HAProxy cartridge using RHC
rhc cartridge-restart --cartridge haproxy
I just dealt with this issue as well, and for me it turned out to be resulting from my AWS healthcheck. Every healthcheck ping created and stored a new session. I fixed this by bypassing store whenever the request is a healthcheck:
app.use(function(req, res, done) {
var isHealthcheck = req.url.indexOf('healthcheck') > -1;
session({
secret: config.secrets.session,
saveUninitialized: true,
resave: false,
store: isHealthcheck || new MongoStore({
mongooseConnection: mongoose.connection,
db: 'myDb'
})
})(req, res, done);
});
So, when isHealthcheck is true, it passes store nothing. When it's not, it does a normal store of the session. The key part here is isHealthCheck ||
.
Hope this helps someone!
来源:https://stackoverflow.com/questions/37695147/connect-mongo-creating-new-session-every-second