Session automatically destroys in Express JS, mongodb, Node js application - node.js

When i close the broswer, the session gets destroyed automatically. Following is the code in my app.js file.
const session = require('express-session');
const MongoSessions = require('connect-mongo')(session);
var mongo = require('mongodb').MongoClient;
var db_url = 'mongodb://localhost:27017/test';
app.use(session({
secret: '007',
resave: false,
saveUninitialized: false,
duration: 40*60 *1000,
activeDuration: 10*60*1000,
store: new MongoSessions({
url: db_url
})
}));
When user logs in , i store the user id of user in a session. When a user again accesses the system, it will redirect him to directly to home page. To check this:
exports.indexPage = function (req, res, next) {
if (req.session.userid == null) {
res.render('login');
} else {
res.render('index');
}
};
It works fine when i keep the browser open but close all tabs and again access the application. When i close the browser and again access the application, it redirects me to login page.

I'm not sure what duration and activeDuration are meant to be, but they aren't valid options for express-session.
Since you're not setting a maxAge value for the session cookie, it automatically becomes limited to the current browser session, meaning that it will be destroyed when you close the browser (as you already noticed).
To prevent that, configure a maximum age (in milliseconds):
app.use(session({
cookie : {
maxAge : 40 * 60 * 1000
},
secret: '007',
...
}));

Related

Passport.js - disconnect specific user

When an administrator blocks a user, I want to disconnect his active session, so that he cannot using the application until the session ends, something like that:
app.post('/admin/users/block-user', (req, res) => {
const { userId } = req.body;
UsersModel.update({ status: 'blocked' }, { where: { id: userId } });
passport.forceLogout(userId)// << ??
})
how do I do it?
Basically you have to use connect-mongostore to store the sessions of each user when they log in. Then you use the existing mongoose connection to do a raw mongodb query to delete a specific user session based on user_id, after hitting the logout api. They will be logged out the next thing they try to do that requires user information on the site.
In app.js:
var session = require('express-session');
var MongoStore = require('connect-mongostore')(session);
app.use(require('express-session')({
secret: 'keyboard cat',
resave: false,
saveUninitialized: false,
store: new MongoStore({mongooseConnection: mongoose.connection})
}));
in my controller file:
mongoose.connection.db.collection('sessions').deleteMany({
"session.passport.user": username
})

Express-Session: How to keep session alive?

I'm currently using express-session with connect-mongodb-session to store sessions and cookies.
This is my implementation:
app.js
const store = new MongoDBStore({
uri: mongoURI,
collection: 'mySessions'
});
app.use(session({
secret: 'whatever',
store: store,
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 30000 // only 30 secs to to help with testing
}
}))
app.use(express.urlencoded({ extended: true }))
app.use(async (req, res, next) => {
console.log('req.session', req.session)
try {
if (req.session && req.session.userId) {
const user = await User.findById(req.session.userId)
req.user = user
req.session.auth = true
res.locals.auth = req.session.auth
} else {
res.locals.auth = null
}
next()
} catch (error) {
console.log('auth middleware error', error)
}
})
Right now I'm using 30 seconds for maxAge so I can test the behaviour of the app.
What happens is if the user closes the browser and comes back before 30 seconds, they remain logged in. Else, the cookie is no longer valid and the user has to log in again. This is ok.
However, if the user is browsing and, after 30 seconds, they make any request, the cookie is no longer active.
I'd like to make like this:
If the user is using the app, but the 30 seconds maxAge is done, the session and cookie are renewed automatically, with a renewed maxAge, so the user doesn't have to log in again while he is using the app.
But if the user closed the browser and came back after maxAge, they are required to login again (which already happens).
Thank you.

node js server propplem

const express = require("express");
const app = express();
var i = new Number;
i=0;
app.get("/", function(req, res){
i++
console.log(i);
});
app.listen(8080);
I created a very small node js project. I have a problem. when I create a variable like above, it doesn't evaluate for each user separately. that is, when a user requests a get, I want it to be 1 each time.
Sample
my problem is that when a jack user enters a site, if he doesn't log out, someone who enters the site's home page from another device enters his account with jack.
how can I do that?
The simplest answer for your question is to simply declare and increment the variable inside the function passed to app.get, but I'm going to assume that you would like a situation where, for a given user's series of requests, the number will increment.
The simplest way to do this is using a server side session, which is provided by the express-session library. Additionally, in order for this to work, you need to call res.end() in order to send the cookie associated with the server session back to the user's browser. More information on sessions generally can be found here.
Below is code to replicate the intent of what you have there, but incrementing for each request from a unique browser instance (identified by the same cookie value associated with the server session):
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({
resave: false,
saveUninitialized: true,
secret: 'secret',
cookie: {
maxAge: 60000
}
}));
app.get('/', function(req, res){
if (!req.session.value) {
req.session.value = 0;
}
req.session.value++;
console.log(req.session.value);
res.end();
});
app.listen(8080);

NodeJS & ExpressJS: How to store user info in session after logged in?

I did lot of research but I am new on this, I couldn't find something concrete.
When a user is logged-in I would like to store some user info in session like Name, Profile_picture, Id, so I can use it for example in the navigation bar.
How can I achieve this?
For example in PHP is too easy just adding this line of code the information stays in what ever page you visit (before session expire)
session_start();
$_SESSION['user_id']
You have to create an express-session: https://www.npmjs.com/package/express-sessions
and then store the session like this:
let session = require("express-session");
app.use(session({
secret: "secret",
resave: false,
saveUninitialized: true,
cookie: {secure: true,
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24
}
}));
This session will be stored during your visit on the webpage. If you want to set values to the cookie, simply request the cookie in a request and set somekind of value:
router.route("/login")
.post(function(req, res) {
req.session.Auth = req.body.user // => user values?
})
You can use express-session or cookie-session(https://www.npmjs.com/package/cookie-session)
If you use cookie session & you made any change session variable or in server side, then no need to restart server.
It will help you to increase your development speed, because you, no need to restart server.
app.use(cookieSession({
name: 'session',
keys: ['key1', 'key2']
}))
app.get('/', function (req, res, next) {
// Update views
req.session.views = (req.session.views || 0) + 1
// Write response
res.end(req.session.views + ' views')
})

Session-only cookie for Express.js

http://www.javascriptkit.com/javatutors/cookie.shtml
Session-only cookies, on the other
hand, stores information in the
browser memory, and is available for
the duration of the browser session.
In other words, the data stored inside
a session cookie is available from the
time of storage until the browser is
closed. Moving from page to page
during this time does not erase the
data.
How can I achieve this using Express.js?
First off, that website is a horrible place to go.
Now on to the question.
What sessions actually are:
Data is stored on the server side.
A cookie is issued which contains an ID.
This ID gets send back to the server on every request, due to the fact that the browser sends the cookies.
Now the server can re-associate the ID in the cookie - commonly called Session ID or short SID - with the session data stored on the server.
Express.js has support for sessions built in.
What the example shows:
Setting up the Express.js middleware
Using a third-party store for saving the session data, in this case Redis (which IMO is overkill for your problem atm)
Installing Redis requires quite some work, but it's also possible to use Express.js's built-in memory store:
var express = require('express');
var app = express.createServer();
var MemoryStore = require('connect/middleware/session/memory');
app.use(express.bodyDecoder());
app.use(express.cookieDecoder());
app.use(express.session({ store: new MemoryStore({ reapInterval: 60000 * 10 }) }));
app.get('/', function(req, res){
req.session.visitCount = req.session.visitCount ? req.session.visitCount + 1 : 1;
res.send('You have visited this page ' + req.session.visitCount + ' times');
});
app.listen(4000);
This will simply keep track of how many times you visited the page, closed your browser and re-opend. The counts will still be there.
You can find more on the options of the MemoryStore, like maximum life time of a session, etc. here.
The following is what I wanted (sort of). When I close browser the information is gone.
var express = require('express');
var app = express.createServer();
var MemoryStore = require('connect/middleware/session/memory');
app.use(express.bodyDecoder());
app.use(express.cookieDecoder());
app.get('/remember', function(req, res) {
res.cookie('rememberme', 'yes', { expires: new Date() - 1, httpOnly: true });
});
app.get('/', function(req, res){
res.send('remember: ' + req.cookies.rememberme);
});
app.listen(4000, '127.0.0.1');
app.use(express.session({cookie: { path: '/', httpOnly: true, maxAge: null }, secret:'eeuqram'}));
The above works on IE8, Firefox and Chrome.
The important piece is maxAge:null
app.get('/remember', function(req, res) {
res.cookie('rememberme', 'yes', { expires: 0, httpOnly: true });
});
This will set session cookie. On browser close it will be erased!
Below is the updated code for Alfred's answer (session using Express.js).
var express = require('express');
var app = express.createServer();
var MemoryStore = require('/home/node/node_modules/connect/lib/middleware/session/memory');
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
key: 'some-key',
secret: 'some-We1rD sEEEEEcret!',
store: new MemoryStore({ reapInterval: 60000 * 10 })
}));
app.get('/', function(req, res) {
req.session.visitCount = req.session.visitCount ? req.session.visitCount + 1 : 1;
res.send('You have visited this page ' + req.session.visitCount + ' times');
});
app.listen(4000);
I know this is an old question but I'm adding an answer since all answers here seem to be either outdated, have security flaws or are just plain wrong.
As of now, express uses the MemoryStore by default, you don't need to explicitly handle that.
Also, as of now, the express-session's official readme page has a stark warning at the beginning to not use MemoryStore as the session store for production, quoting:
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.
For a list of stores, see compatible session stores.
Here's a simple solution with connect-mongodb-session if you want to use MongoDBStore for session storage:
import express from 'express';
import session from 'express-session';
import ConnectMongoDbSession from 'connect-mongodb-session';
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(session({
secret: < COOKIE_SECRET >,
name: 'sessionId', // Don't use the default name, see http://expressjs.com/en/advanced/best-practice-security.html
cookie: {
httpOnly: true,
secure: true, // Remove this if you're not using HTTPS, but it will be a massive security flaw
sameSite: 'strict',
},
store: getStore(),
// Boilerplate options, see:
// * https://www.npmjs.com/package/express-session#resave
// * https://www.npmjs.com/package/express-session#saveuninitialized
resave: true,
saveUninitialized: true,
}));
function getStore() {
const MongoDBStore = ConnectMongoDbSession(session);
const store = new MongoDBStore({
uri: < DATABASE_URI >,
collection: < SESSION_COLLECTION_NAME >,
connectionOptions: {
useNewUrlParser: true,
useUnifiedTopology: true,
},
});
store.on('error', (error: any) => {
console.error(error);
});
return store;
}

Resources