Passport.js - disconnect specific user - node.js

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
})

Related

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.

Express.js Session storage persistence issue

I'm having a really odd issue with session storage using mongoDB and passport.
When a user logs in, the session is created and passed to mongo as expected as well as the passport id.
{
"_id" : "GEEFIDhiMehdjPvtxRmPy_Kuls2IdVsx",
"expires" : ISODate("2020-06-10T03:09:30.396Z"),
"session" : "{\"cookie\":{\"originalMaxAge\":28800000,\"expires\":\"2020-06-10T03:09:29.358Z\",\"httpOnly\":true,\"path\":\"/\"},\"passport\":{\"user\":\"ebf7d73d-f3f2-4f96-8123-3f0f262ffff6\"}}"
}
However, when the express server is restarted passport clears the user out of the sessions storage when a user selects a route that requires auth (there by invoking the isAuth function). Meaning users are required to login in after server restart.
{
"_id" : "GEEFIDhiMehdjPvtxRmPy_Kuls2IdVsx",
"expires" : ISODate("2020-06-10T03:11:54.464Z"),
"session" : "{\"cookie\":{\"originalMaxAge\":28800000,\"expires\":\"2020-06-10T03:11:54.464Z\",\"httpOnly\":true,\"path\":\"/\"},\"passport\":{}}"
}
My auth code is pretty standard stuff tbh, where am I going wrong here? I'm using the azure-ad passport strategy.
const passport = require('passport');
const OIDCStrategy = require('passport-azure-ad').OIDCStrategy;
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const config = require('../config');
const store = new MongoStore({
url: config.databaseUri,
});
// Usual passport code here findbyoid, ensureAuthenticated etc
function setupPassport(app) {
app.use(
session({
secret: 'somepassword',
resave: true,
cookie: {
maxAge: 8 * 60 * 60 * 1000,
},
saveUninitialized: true,
store: store,
})
);
app.use(passport.initialize());
app.use(passport.session());
}
I wasn't actually storing the correct user information in the session or even looking in the session for the user information. Instead I was storing users in a local array and looking up their oid with deserializeUser function. the solution was to replace this with the code below.
passport.serializeUser(function (user, done) {
done(null, user);
});
passport.deserializeUser(async (user, done) => {
done(null, user);
});
This way the user object was stored in the session database and then recollected when a user checked auth.

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 automatically destroys in Express JS, mongodb, Node js application

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',
...
}));

Session in nodejs

sorry for newby question, but can you explain me how to use sessions in nodeJS. I read a lot of articles in internet but I didn't success to implement something for my purpose (data is saving the session, but every new request session is empty), can you give example from the beginning how to initialize and how to use.
Purpose: when user do login in the system, I need to open session for him and every request that he will send in the future I need to check is his session exist?
I'm using express 4.x. I do it like:
// init session
app.use(cookieParser());
app.use(session({
secret : "yepiMobileSession",
resave : true,
key : "session",
store: mongooseSession(daoService.mongoose),
saveUninitialized : true
}));
// save user to the session
request.session[CONST.SESSION_USER] = user;
// Check login
function checkLogin(id){
var user = request.session[CONST.SESSION_USER];
if (user && request.params.clientData && user._id == id){
return true;
} else {
return false;
}
}
You can take a look at the following code. I think this will help you.
var app = require('express')(),
expressSession = require('express-session'),
cookieParser = require('cookie-parser');
app.use(cookieParser());
app.use(expressSession({
secret: 'mYsEcReTkEy',
resave: true,
saveUninitialized: true
}));// I haven't used the session store
//setting session
app.post('/login', function(req,res){
var id=12345;
req.session.userId = id;
res.send(200);
});
//getting session
app.get('/hello', function(req,res){
var id=req.session.userId;
console.log("Hello",id);
res.send(200);
});
But node server and client have to be in same domain.

Resources