I am using Node.js/Express with the 'express-session' module for session management. My setup is as follows:
var session = require('express-session');
var MemoryStore = require('memorystore')(session)
const express = require('express');
const app = express();
app.use(session({
cookie: { maxAge: 86400000 },
store: new MemoryStore({
checkPeriod: 86400000 // prune expired entries every 24h
}),
resave: false,
saveUninitialized: false,
unset: 'destroy',
secret: process.env.COOKIE_SECRET
}))
My question is simple...how do I call the 'store' commands (for example ".all", ".destroy", ".length", etc)...? I have attempted at least the following:
session.store.all(function(error, len) {console.log("EXECUTED MEMORYSTORE LIST: ");})
MemoryStore.all(function(error, len) {console.log("EXECUTED MEMORYSTORE LIST: ");})
store.all(function(error, len) {console.log("EXECUTED MEMORYSTORE LIST: ");})
...Nothing of which works...I always get a "not a function" error thrown. I would like to access these commands to enable cycling through the sessions in the store, deleting as necessary, and other misc tasks.
Any advice on how to access these 'store commands' would be greatly appreciated. I thank you in advance.
If you want access to the MemoryStore interface for that module, then you just have to save the instance to your own variable:
const memoryStore = new MemoryStore({
checkPeriod: 86400000 // prune expired entries every 24h
});
app.use(session({
cookie: { maxAge: 86400000 },
store: memoryStore,
resave: false,
saveUninitialized: false,
unset: 'destroy',
secret: process.env.COOKIE_SECRET
}));
Now, you have access to the instance of the memoryStore and you can access whatever methods it has. You can see what methods it offers in the code here. It's implementation is really just in service of the express-session store interface - it is not meant as a separately accessible database, but you can call the methods from the express-session store interface.
Keep in mind that the tasks you ask about are better served by using a session store that is a real database and has a real database interface. Then, you can use the regular database interface to access previously store session data.
Related
I notice that some of the project will use redis store and express session to save the user session
For example:
const session = require('express-session');
var redis = require("redis");
var redisStore = require('connect-redis')(session);
var client = redis.createClient();
var app = express();
app.use(session({
secret: 'scret',
store: new redisStore({
host: '127.0.0.1',
port: 6379,
client: client,
ttl : 7200
}),
saveUninitialized: true,
// rolling: false,
resave: true,
cookie: {
maxAge: 2 * 60 * 60 * 1000
}
}));
What is the reason that we need to use these two Session Management function at the same time?
express-session can be set up with different "stores" to save session data.
MemoryStore comes with the package express-session.
The authors of express-session warn about this default store.
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.
Redis is one of the compatible session stores and in this case is used "as a replacement" of a default store.
I am using express-session for a login system for users on my Node.js web application. My issue is that every time I make an update and restart the Node.js server, all the users are logged off which is not ideal behaviour (there are multiple users logged on via the local network and I would like to not have to log them back on each time there is a restart).
From my understanding I could use something such as connect-pg-simple (for reference I am using a postgres database with my node web app) to keep users logged in on server restart but I am unsure of how to implement this.
I know it would be something along the lines of:
app.use(session({
store: new (require('connect-pg-simple')(session))({
// Insert connect-pg-simple options here
}),
secret: 'secret',
resave: false,
saveUninitialized: true
}));
But I do not know what options to use or how to save the users session even on server restart.
Yes you are on the right track.
Open your database and create a table named session. See: https://github.com/voxpelli/node-connect-pg-simple/blob/HEAD/table.sql
Add the connect-pg-simple code like you posted
Pass the postgres pool you are using from node-pg.
const session = require('express-session')
const PGSessionStore = require('connect-pg-simple')(session)
const pg = require('pg')
const pool = new pg.Pool({
user: process.env.PG_USERNAME,
host: process.env.PG_HOST,
database: process.env.PG_DATABASE,
password: process.env.PG_PASSWORD,
port: process.env.PG_PORT
})
app.use(session({
store: new PGSessionStore({
pool: pool,
tableName: 'session'
}),
secret: process.env.COOKIE_SECRET,
cookie: {
secure: false,
httpOnly: true,
sameSite: true,
maxAge: 24 * 60 * 60 * 1000
},
saveUninitialized: true,
resave: false
}))
Your session is stored on the app runtime, so on refresh, it resets back every other data it might be holding at runtime on server restart
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
So I'm using express-session https://github.com/expressjs/session and I was wondering if the secret needed to be unique for every user. I can't seem to find anything that says it does as the usage just lists:
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
I'm currently just creating the secret using bcrypt but I'm not sure if this will impact sessions when I update my server file.
var salt1 = bcrypt.genSaltSync();
var salt2 = bcrypt.genSaltSync();
var secret = bcrypt.hashSync(salt1 + salt2, 10);
app.use(session({
secret, // set this to a long random string!,
}));
Should the session be generated inside a function in itself, i.e. function generateSession()
The secret is the same for all users. The "secret" you supply simply acts as the salt for the session's hash function. The method you're using is as good as any as it will generate a new salt each time the application is restarted.
I'm lazily changing my user schema (mongoose). My code will rewrite a user's data when a user logs in and is still using the old schema.
To ensure no user is already logged in with the old schema when the new version gets deployed (which would throw errors), I want to log out all users and delete their user sessions when the app restarts.
I'm using passportJS and saving the sessions with cookie-session.
app.use(cookieParser(env.cookie))
app.use(cookieSession({
cookie: {maxAge: 60000},
secret: 'ThisIsASecret',
saveUninitialized: true,
resave: true
}))
require('./config/passport')(passport)
app.use(passport.initialize())
app.use(passport.session())
It might not be the most elegant solution, but changing the cookie-session secret string works:
app.use(cookieSession({
cookie: {maxAge: 60000},
secret: 'ThisHasChanged',
saveUninitialized: true,
resave: true
}))