express-session: Rolling session expiry configuration - node.js

So I'm using express-session with a mongo store like so:
app.use(session({
secret: 'some secret here',
saveUninitialized: false,
resave: false,
store: new MongoStore({
url: 'http://someurlhere'
})
}));
I have some login middleware, which after a successful login I want to then set the session cookie expiry time.
So I am testing with a 10 second expiry time right now using
req.session.cookie.expires = new Date(Date.now() + 10000);
I want the session expiry to reset for each subsequent request. Currently after 10 seconds have elapsed, no matter how many requests I have made after logging in, the session expires.
I feel like I have misunderstood something here!
EDIT
Ok so I missed the rolling config option in the docs, but even when I set this to true in my session config options, the same behaviour occurs:
app.use(session({
secret: 'some secret here',
saveUninitialized: false,
resave: false,
store: new MongoStore({
url: 'http://someurlhere'
}),
rolling: true,
cookie: {
maxAge: 10000
}
}));
I am now console logging the value of the cookie maxAge across my routes and see it decreasing as each subsequent request is made after logging in, it never reset back to 10000.
What am I doing wrong?
SOLVED
Ok so I came across a comment on this issue
I changed resave to true and it works as expected now.

Related

Express Session expiry vs First Time Loging in

How to differentiate whether the session expired or is it the first time logging in.
I am setting the session like this and storing the data in express-mysql-session.
const sessionStore = new MySQLStore({}, connection);
// session
const adminSession = session({
secret: process.env.ADMIN_SECRET,
resave: false,
saveUninitialized: false,
store: sessionStore,
name: "adminSession",
cookie: {
maxAge: 600000,
secure: false,
},
});
app.use("/api/admin", adminSession, adminRoutes);
//admin login
app.post("/api/admin/login",(req,res)=>{
req.session.adminAuthenticated = true;
});
By simply checking if there is req.session.adminAuthenticated, I can know if admin is logged in or not. But how can I know if the admin had already logged in earlier but the session expired.
Any help with this.

How do I set a session expiration date in redis node.js without maxAge?

I have this code:
const redisClient = redis.createClient({
host: 'localhost',
port: 6379,
ttl: 10
});
app.use(session({
store: new RedisStore({ client: redisClient });,
secret: 'some secret',
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
sameSite: true,
maxAge: 60*1000
}
}));
And everything works as it should. After the maxAge expires, redis is also cleared. But if you delete maxAge and leave ttl, then redis will never be cleared, how to clear redis without specifying maxAge, because the user can change the value of the cookie maxAge to null, and then redis will never be cleared. Can I somehow specify the expiration time directly in redis and not in cookies? Or did I get something wrong? Thank you in advance.
As you can see in connect-redis docs under the ttl option - "If the session cookie has a expires date, connect-redis will use it as the TTL.".
So in you're case - both the cookie and the key in redis will be cleared on expiration.
And even if the client will somehow change the cookie expiration time, it won't effect redis (so the cookie might be sent over the HTTP request, but the server won't recognize it).
(You didn't mentioned which modules you're using, I'm just assuming its express-session and connect-redis)

express-session Changes the session when the browser is closed

Server on express (4.16.3), with it the express-session (1.15.6) module works.
Code:
// ...
app.use(session({
secret: 'mySecret',
resave: false,
saveUninitialized: true,
store: new MongoDBStore({
uri: 'my-url',
collection: 'sessions'
})
}))
// ...
The essence of the problem: I open the Yandex browser - assign a session, then close it and when I reopen it - a new session. The matter is that authorization is tied to sessions.
The problem is observed in the Yandex browser, microsoft EDGE and in all mobile browsers, while in chrome and opera works correctly.
Help solve the problem or maybe something can replace the module express-sessions
This is happening because your browser default expire the cookie when the browser is closed. In order to fix you can add cookie:{ maxAge: 60000} to your session.
app.use(session({
secret: 'mySecret',
resave: false,
cookie:{ maxAge: 60000},
saveUninitialized: true,
store: new MongoDBStore({
uri: 'my-url',
collection: 'sessions'
})
if you want to make the cookie to not expire, the best way is to set a large number.
// this will it expire in 200 years
cookie: { maxAge: 9000000000000}
or a very far future date in expire property.
// this will expire in year 9999
cookie: {expires: new Date(253402300000000)}

Log out all users with passport and cookie-session

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

Renewing/Refreshing Express Session

In my app I restrict some access to some actions and pages if a user is not logged in. I have:
var restrict = function(req, res, next) {
if (!req.user) {
console.log("USER isn't logged in.")
return res.status(403).send('Access or action denied, please log in');
}
next();
}
app.get('/stocks', restrict, MainHandler.findAllStocksFromUser);
app.get('/stocks/:id', MainHandler.findStockByIdAndDates);
app.put('/stocks/:id/stockActions', restrict, MainHandler.handleStockAction);
I'm essentially trying to refresh a session everytime the client makes a request to the server so that the server doesn't logout the user/destroy the session when it shouldn't. For testing, I want the session to expire/the user to be logged out if 20 seconds go by without the user making an requests to the server. I have:
app.use(session({secret: 'secret', saveUninitialized: true, resave: true, expires: new Date(Date.now() + (20000))}));
Then I try to use middleware to refresh the expiration date every time the use makes a request:
// Session-persisted message middleware
app.use(function(req, res, next){
req.session.cookie.expires = new Date(Date.now() + 20000);
next();
});
But if I log in from the client, and click around, causing requests to the server, I still get the log-in error on the client after 20 seconds, despite trying to "refresh" the session in the middleware. I have also tried using maxAge using the same strategy with the middleware. Any ideas? Thanks!
You can try define your session as follows
app.use (
session ({
secret: "secret",
saveUninitialized: true,
resave: true,
cookie: {
expires: 20 * 1000
}
})
);
and then refresh the session using
req.session.touch()
or you could define your session as
app.use (
session ({
secret: "secret",
saveUninitialized: false,
resave: true,
rolling: true,
cookie: {
expires: 20 * 1000
}
})
);
and it will renew the session automatically and it will only expire when it has been idle for the value in the expires variable
express-session supports a duration-based maxAge setting, which will work better than setting a fixed date for all sessions. So your middleware usage should instead look like:
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true,
maxAge: 20000
}));
Next, to update the expiration of the session, you can just call req.session.touch(); if that is all you're doing to the session and its contents.
The documentation has a lot of other good information on controlling session expiration and related topics.

Resources