express-session Changes the session when the browser is closed - node.js

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

Related

Express doesn't set-cookie when SameSite is none

I have read a lot of other similar questions, but I couldn't solve the issue.
My setup is Node + Express + PassportJs and everything works in development, but I have problems on production.
With the following code, I see that the session cookie is sent back in the response, but I also get a message saying that it won't be applied as SameSite is lax (the default) and the response comes from another site (frontend and backend do not have the same origin).
app.use(
session({
secret: "foo",
resave: false,
saveUninitialized: false,
store: MongoStore.create({ mongoUrl: process.env.MONGO_DB_CONN_STRING! }),
cookie: { httpOnly: true }
})
);
So I changed it to this, so to specify SameSite and Secure in production, but at this point, no cookie is set anymore!
app.use(
session({
secret: "foo",
resave: false,
saveUninitialized: false,
store: MongoStore.create({ mongoUrl: process.env.MONGO_DB_CONN_STRING! }),
cookie: isProduction ? { httpOnly: true, sameSite: "none", secure: true } : {} // <-- only change
})
);
What could be the cause? I've tried to fix it by playing with CORS (no success) and other 100 things. Yet it seems some quirk I am missing.
depending on what service you use to deploy your API(netlify, render.com, heroku other...) you have to enable proxy
this.app.enable('trust proxy');
it fixed my issue

Why can't I set cookies over HTTPS?

I have a server that has its own domain and is using HTTPS. I have a website that has its own domain and is using HTTPS as well.
On the home page of the website, there is a login button and a sign up button. Both buttons lead to forms to execute their respective tasks, and both forms send requests to the server that respond with cookies, or at least that's what they are supposed to do.
I am using express-session in combination with Redis to store the session ids. Here is the config for that (connectToRedis is simply a function that returns a RedisClient):
const RedisStore = connectRedis(session);
const redisClient = await connectToRedis();
app.use(
session({
store: new RedisStore({
client: redisClient,
}),
cookie: {
httpOnly: true,
secure: true,
sameSite: "lax",
maxAge: TEN_YEARS,
},
resave: false,
saveUninitialized: false,
secret: SECRET,
name: AUTH_COOKIE,
})
);
For some reason the cookies are not being sent in the requests. The Set-Cookie header isn't even showing up! I tried changing SameSite to none (article), but that didn't work.
This is my first time deploying a production website, so all this HTTPS stuff is kind of new to me.
Thanks for your help, and if you need any extra information, please let me know.
IMPORTANT UPDATE:
Finally, I have made some progress (all it took was a pizza break).
I added the path key to my cookie config and gave it the value of /. I also set proxy to true.
So now it looks like this:
const RedisStore = connectRedis(session);
const redisClient = await connectToRedis();
app.use(
session({
store: new RedisStore({
client: redisClient,
}),
cookie: {
httpOnly: true,
secure: true,
sameSite: "none",
maxAge: TEN_YEARS,
path: "/",
},
resave: false,
saveUninitialized: false,
secret: SECRET,
name: AUTH_COOKIE,
proxy: true,
})
);
With this, the cookie is finally appearing in the requests, but it isn't being set in the browser...

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

express-session: Rolling session expiry configuration

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.

connect-mongo cross-domains session issue

I am having a problem with sessions across sub-domains
I use connect mongo like so:
app.use(session({ // req.session is populated
secret: 'xxxxxx',
saveUninitialized: true,
resave: true,
store: new MongoStore({
db: 'nnn'
}),
cookie: {
path: '/',
maxAge: new Date(Date.now() + time),
domain : 'mydomain.com' ,
httpOnly: true
}
}));
However, when I redirect to a subdomain xyz.mydomian.com the session is invalidated. Can anyone recommend a strategy for getting cross domain login to work with connect-mongo ?

Resources