nodejs session storage - node.js

In the connect-mongodb module we can store session in MongoDB like this:
var connect = require('connect')
, Db = require('mongodb').Db
, Server = require('mongodb').Server
, server_config = new Server('localhost', 27017, {auto_reconnect: true, native_parser: true})
, db = new Db('test', server_config, {})
, mongoStore = require('connect-mongodb');
connect.createServer(
connect.bodyParser(),
connect.cookieParser(),
connect.session({
cookie: {maxAge: 60000 * 20} // 20 minutes
, secret: 'foo'
, store: new mongoStore({db: db})
})
);
In the example above we have to use native mongodb stuff. In my nodejs project I use mongoose 2.4.1 so how should rewrite that code to use mongoose?
Thanks!

If you are using mongoose and you used mongoose.connect, you can get the connection at
mongoose.connection
So to configure the session store you can use this form
var mongoose = require('mongoose'),
mongoStore = require('connect-mongodb');
...
mongoose.connect(host,databaseName,port);
// mongoose.connect('mongodb://host:port/databaseName');
...
connect.session({
secret: 'your secret key',
cookie: { maxAge : 60*15*1000}, // 15 minutes, in milliseconds
store: new mongoStore( { db : mongoose.connection.db })
})

You have no reason to do that, just use sessions with connect-mongodb which has all the 'Session Store' Express functionality implemented. Use Mongoose for everything else which requires db storage, but leave the sessions for connect-mongodb.
Here's a real example that does that: https://github.com/alexyoung/nodepad

Mongoose should expose the connection somehow.

If you use connect-mongo, pass your mongoose connection like this:
var express = require('express');
var MongoStore = require('connect-mongo')(express);
new MongoStore({ mongoose_connection: mongoose.connection })
And everything will work as you'd expect.

Related

Mongoose and connect-mongo

I am using mongoose for managing relationships between data and I am trying to use connect-mongo to store specific sessions in the database.
It looks like that we need to connect twice to the db, one with mongoose and another one with connect-mongo.
I am using the following code to initialise a connection for mongoose
await mongoose.connect(this._connectionUrl, this._connectionOptions);
Initialising a new store every time (not sure if I am correct regarding code initialisation).
app.use(session({
// secret: config.sessionSecretKey,
secret: "secretkey",
resave: true,
saveUninitialized: true,
cookie: { maxAge: 19 * 60000 }, // store for 19 minutes
store: MongoStore.create({
mongoUrl: this._connectionUrl,
mongoOptions: this._connectionOptions // See below for details
})
}))
Is there any way that I can pass the connection from mongoose to mongo-connect Store?
i'm lookin for a solution too and just read this on the "migration guide" of connect-mongo
For the options, you should make the following changes:
Change url to mongoUrl Change collection to collectionName if you are
using it Keep clientPromise if you are using it mongooseConnection has
been removed. Please update your application code to use either
mongoUrl, client or clientPromise To reuse an existing mongoose
connection retreive the mongoDb driver from you mongoose connection
using Connection.prototype.getClient() and pass it to the store in the
client-option. Remove fallbackMemory option and if you are using it,
and there's this example https://github.com/jdesboeufs/connect-mongo/blob/master/example/mongoose.js
I've just been digging through the docs and through a few other SO responses. I've found this works really well with the new version of connect-mongo.
const session = require('express-session');
const MongoStore = require('connect-mongo');
app.use(
session({
secret: "secretkey",
resave: true,
saveUninitialized: true,
cookie: { maxAge: 19 * 60000 }, // store for 19 minutes
store: MongoStore.create({
client: mongoose.connection.getClient()
})
})
);
It is recommended by the devs for connect-mongo to utilise the connection object for mongoose to retrieve the client to ride the same connection so you don't have to setup two separate connections. This seems like a really clean way to do it but comment if you spot anything off!
This was pulled from the bottom of the connect-mongo migration guide here

Express session won't persist, even with MongoStore using connect-mongo

When I restart my server, my session ends and I am logged out. This does not happen on a regular page refresh. I am using connect-mongo to remedy this:
var session = require('express-session');
const MongoStore = require('connect-mongo')(session);
Here is the code I am using to store my session, reusing an existing Mongo connection called thisDb:
app.use(session({
secret: secretHash,
saveUninitialized: true,
resave: true,
secure: false,
store: new MongoStore({ db: thisDb })
}));
During a successful log in:
var day = 60000*60*24;
req.session.expires = new Date(Date.now() + (30*day));
req.session.cookie.maxAge = (30*day);
In my Mongo shell, I can verify that a new session is created when I log in:
db.sessions.find()
{"cookie":{"originalMaxAge":2592000000,"expires":"2017-11-17T20:36:12.777Z","httpOnly":true,"path":"/"},"user":{"newNotifications":false,"username":"max","admin":"true","moderator":"true"},"expires":"2017-11-17T20:36:10.556Z"}
Well, almost 3 years later i was having this issue. Don't know if OP was using Passport but i resolved this issue by moving this functions from inside the passport.use function to outside:
passport.serializeUser(function(user, done){
done(null,user.id);
});
passport.deserializeUser((id,done) => {
User.findById(id, (err,user) => {
done(null,user);
});
});

Best Session Storage Middleware for Express + PostgreSQL

I'm looking for sessionstore for production app because I have error message:
Warning: connect.session() MemoryStore is not designed for a
production environment, as it will leak memory, and will not scale
past a single process
My code:
var express = require('express');
var ECT = require('ect');
var cookieParser = require('cookie-parser');
var compress = require('compression');
var session = require('express-session');
var bodyParser = require('body-parser');
var _ = require('lodash');
var passport = require('passport');
var expressValidator = require('express-validator');
var connectAssets = require('connect-assets');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressValidator());
app.use(methodOverride());
app.use(cookieParser());
app.use(session({
resave: true,
saveUninitialized: true,
secret: secrets.sessionSecret,
}));
app.use(passport.initialize());
app.use(passport.session());
var app = module.exports = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(app.get('port'), function() {
console.log('Express server listening on port %d in %s mode', app.get('port'), app.get('env'));
});
module.exports = app;
I don't know what is the best solution for my production app. I'm using sequelize as ORM with PostgreSQL.
I will be very grateful with any opinion.
Though an answer has been accepted, I think a more elaborated answer is in order, so that people who actually want to use Express with PostgreSQL for consistent session storage can have a proper reference.
Express has the session module to handle the sessions though it defaults to in-memory storage that is suitable for development stages but not for production
Warning The default server-side session storage, MemoryStore, is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing.
So for PostgreSQL there is a dedicated simple connector called connect pg simple
Once you import the connect-pg-simple you . need to pass it the session import like this:
const session = require('express-session')
const pgSession = require('connect-pg-simple')(session)
When you add the session as middleware you'll have to pass it its settings
app.use(session(sessionConfig))
and in your sessionConfig, this would be where you set all your session parameters you need to add a store option that would look like this (adding the full set of options though for the matter at hand just note the store option):
const sessionConfig = {
store: new pgSession({
pool: sessionDBaccess,
tableName: 'session'
}),
name: 'SID',
secret: randomString.generate({
length: 14,
charset: 'alphanumeric'
}),
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 1000 * 60 * 60 * 24 * 7,
aameSite: true,
secure: false // ENABLE ONLY ON HTTPS
}}
The new instance of pgSesision takes two options, the pool which is the config setup to access the PostgreSQL DB and the table name.
The DB connection setting should look like this:
const sessionDBaccess = new sessionPool({
user: DB_USER,
password: DB_PASS,
host: DB_HOST,
port: DB_PORT,
database: DB_NAME})
Also note that the session pool must be initiated:
const sessionPool = require('pg').Pool
I got it working with connect-pg-simple.
Create a session table with the provided table.sql, and pass in a connection string or an object.
If you have just to store session you can use redis or maybe mongoDB if you want persistence.

Instance of connect-mongo module do nothing

Hie. I've a problem. I use windows and my app is a nodejs app. I store sessions in mongodb and use connect-mongo module. And this is my problem:
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var sessionStore = new MongoStore({ url: 'mongodb://localhost/latte', db: 'latte' }, function(err) {
console.log(arguments);
// ... some code use sessionStore variable ...
var server = http.createServer(app);
server.listen('80', 'latte.ru', function(){
log.info('Express server listening on port 80');
});
});
When I create an instance of MongoStore callback doesn't fire and console.log doesn't fire too, but I have no errors in console.
When I run server without of MongoStore all is OK.
In windows console mongo works fine.
Please help to resolve this problem.
Try with this,
var sessionStore = new MongoStore({ host: 'localhost', port: 27017, db: 'test-app'}, function(err){
console.log(arguments)
});
Your MongoStore url doesn't appear to be in sync.

How to set up mongoose and connect-mongo?

I had an Error setting TTL error when starting my application in express. Maybe the problem is because I use for sessions and for db operations the same database through different connections.
So it there a specific sequence of requiring connect-mongo and mongoose that needs to be respected if I want to store my sessions in mongodb via the connect-mongo middleware and use mongo as my database for my app specific data?
Currently my app looks like this:
App.app.use(express.session({
store: new MongoStore({
db: settings.cookie.db,
host: settings.cookie.host,
port: settings.cookie.port
}),
secret: settings.cookie.secret
}))
and later I set start the connection for mongo:
function connect(connectionString) {
mongoose.connect(connectionString)
var db = mongoose.connection
db.on('error', console.error.bind(console, 'connection error'))
db.once('open', function callbck() {
console.log('Mongoose connected at: ', connectionString)
})
}
There are no error logs apart
Also how do I tear down properly mongo connections when I close my app (from command line let's say)? For this question I found the answer here I think.
First of all i've created a sessionStore module
var mongoose = require('mongoose'),
express = require('express'),
MongoStore = require('connect-mongo')(express),
sessionStore = new MongoStore({mongoose_connection: mongoose.connection});
module.exports = sessionStore;
Then i've included it into app
sessionStore = require('libs/sessionStore');
And finaly
app.use(express.session({
secret: config.get('session:secret'),
key: config.get('session:key'),
cookie: config.get('session:cookie'),
store: sessionStore
}));
That's config
"session": {
"secret": "secret",
"key": "connect.sid",
"cookie": {
"path": "/",
"httpOnly": true,
"maxAge": null
}
},

Resources