Express.js sessions reset at server restart - node.js

I am using the express-session package with a custom MongoDB based session store, but for some reason the sessions are deleted everytime I stop and re-run the script.
From looking at the database I can see that the sessions are saved.
Any ideas?

You can use connect-mongo for storing sessions in database so that it would persist even after restarting the node server.
Here is an example on how you can use it. Example is from its Readme.
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
app.use(session({
secret: settings.cookie_secret,
store: new MongoStore({
db : settings.db,
})
}));

Related

Develop Node + Express applications with user authentication without having to log into an account each server change?

I am developing a website heavily embedded with user authentication (using passport). I also have nodemon reloading the server after each server change. However it is quite tedious to have to log in as a user each time to test a new change. Is there a way to avoid having to constantly log in as a user to test every single new server change? I can not find any npm modules that fake a persistent user or solve the problem. Thanks!
The Answer - If you are in a similar situation use this code.
Came back with a solution that works, so for anyone who sees this post in the future. This is how you get simple persistent user authentication. With passport. This assumes you have strategies in place already, and as just tring to make the users stay after server restarts.
var bodyParser = require('body-parser')
var mongoose = require('mongoose');
var session = require('express-session');
var cookieParser = require('cookie-parser');
const MongoStore = require('connect-mongo')(session);
app.use(session({
resave: true,
saveUninitialized: true,
secret: 'add-secret',
store: new MongoStore({
url: process.env.MONGODB_URI || "mongodb://localhost/add-url",
autoReconnect: true,
clear_interval: 3600
})
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
Yup - it sounds like that's EXACTLY what you want: a "mock authentication" module (for testing purposes only).
Here are two possibilities; you might also consider writing your own:
passport-stub
passport-mocked

Node/Express with connect-redis, how handle session expiry

I have a Node/Express application that use redis as session store.
I have a question concerning the handling of the expiry of the session.
I'd like have an active session until the browser is closed, so I didn't set a session expiration time.
Doing that the session cookie works fine, but I have a doubt about Redis.
It seems that the couple Key/Value stored in Redis DB never expire.
How is the right way to handle this?
There is a way to configure redis to destroy a value stored with a certain idle time?
Or is better set a TTL when the connect-redis is invoked inside the application?
Actual configuration of the session inside the application:
var session = require('express-session');
var RedisStore = require('connect-redis')(session);
app.use(session({
store: new RedisStore({port:6379, host: 'localhost'}),
secret: "my-secret-here",
resave: false,
saveUninitialized: true }));
Using Redis with express-session, you can use the touch() method from express-session to reset the TTL. So if you set a TTL when creating the session, do something like this on the routes where you don't want the session to expire:
api.get("/someRoute/", (req, res) => {
req.session.touch();
// Whatever else you need to do
res.sendStatus(200);
}
That will reset the TTL on Redis and prevent the session from expiring assuming the client is still hitting your API - I'm assuming that if the client doesn't interact with your API for long enough, that implies the browser is closed or otherwise finished using your app.
You can specify a ttl while creating the session store.
You can find more options in the readme.
app.use(session({
store: new RedisStore(options),
secret: 'keyboard cat',
ttl : 20 // ttl is in seconds. From the readme.
}));

Express and Redis - If session exists for this user, don't allow access

I am using Redis and Express like this:
// app.js
var redis = require('redis'),
redisClient = redis.createClient(),
session = require('express-session'),
RedisStore = require('connect-redis')(session);
session = session({
store: new RedisStore({client: redisClient}),
secret: 'secretKey',
resave: true,
saveUninitialized: true
})
app.use(session);
In my index route file, I set a user session like this:
req.session.user = user;
When this user comes back (or opens another tab), how could I detect how many sessions he is currently having and block him access if he already has one active session?
express-session working via cookies. So you had cookie named session with some sessionId. All tabs inside browsed share cookies and you can't rely on cookies if you want to strict working via only one browser tab.
You need to create your own Sessions for each opened browser tab. Something like generating tabId at client side and saving {userId, tabId} to Redis
Or you can use websockets (http://socket.io/) for that, a little overhead, but doing exactly what you want

Preserving session between node.js server reboots

I'm developing a node.js app and I use nodemon to run it. My question is how I do to keep the session open when I make a change in the server, and nodemon reboot.
This answer assumes that you're using Express or Koa, two of the more popular node.js web frameworks.
In your application, you probably have a line that says the following.
Express 4
var app = require( 'express' )()
var session = require( 'express-session' )
app.use( session() ) // this is the session middleware
KoaJS
var app = require( 'koa' )()
var session = require( 'koa-session' )
app.use( session() ) // this is the session middleware
The guiding wisdom in web applications is to make the world-facing side of it as stateless as possible. This means that your node.js server holds no information between requests and can be destroyed and restarted anytime.
A session is a very stateful thing. Because of this, you need to store session data in something designed to keep the data uncorrupted in the long run. This is most commonly done through a database (more secure) or a browser cookie (less secure).
The express-session module holds session information in memory by default. This violates the stateless ideals and will lose session information on reboot.
The koa-session module uses cookies by default. This is stateless, but raises some security concerns in that it may be possible for users to modify their own session variables, so don't use this for billing or other sensitive operations.
In both of the above modules, you can override the defaults with your own session store.
Redis Session Store
I normally store session data in a database like redis.
Express
This can be easily wired into express with a module like connect-redis.
Quoting from the Readme:
var session = require('express-session');
var RedisStore = require('connect-redis')(session);
app.use(session({
store: new RedisStore(options),
secret: 'keyboard cat'
}));
KoaJS
Using redis to store session data is also possible in koa with the koa-redis module.
Paraphrasing from the Readme:
var app require('koa')();
var session = require('koa-generic-session');
var redisStore = require('koa-redis');
app.keys = ['keys', 'keykeys'];
app.use(session({
store: redisStore()
}));
app.use(function *() {
this.session.name = 'koa-redis';
});
No Databases Session Store
Express
Express can store session data in cookies with the cookie-session extension.
Koa
As mentioned before, the koa-session module stores sessions in cookies by default.

req.user after restart node

I've attached passportjs to authenticate user on my site. I use localStrategy and all works fine. But I have some problem (may be it's feature of passportjs) - after restart node, req.user is undefined and users should login again.
What should I do to initialize req.user on start server??
LocalStrategy stores user credentials in memory after login. This means that when you restart node, the credentials will inevitably be lost.
However, passport does use the session cookie functionality in express, so you can persist cookies in the standard express way.
This is quite easy using the RedisStore module, to which you pass the express object:
var express = require('express');
var RedisStore = require('connect-redis')(express);
Before you set up passport, enable session persistence to redis in express:
app.use(express.cookieParser());
app.use(express.session({
secret: "a-secret-token",
store : new RedisStore({
host : 'redis-hostname',
port : 'redis-port',
user : 'redis-username',
pass : 'redis-password'
}),
cookie : {
maxAge : 604800 // one week
}
}));
app.use(passport.initialize());
app.use(passport.session());
You'll need to install redis on your machine, and change the details above to match the redis instance you want to connect to.
You need to store user login info in Redis for e.g. because after restart, all your variables that you set will be undefined

Resources