I'm using NodeJS an express session handling with Redis. Here is the interesting part:
let session = require('express-session')
let cookieParser = require('cookie-parser')
let Redis = require('ioredis');
let clientRedis = new Redis();
let RedisStore = require('connect-redis')(session);
const SESSIONSECRET = require(config.get('app.secretsession')).secret;
app.use(cookieParser(SESSIONSECRET));
const sessionMiddleware = session({
store: new RedisStore({
client: clientRedis,
}),
secret: SESSIONSECRET,
resave: true,
saveUninitialized: true,
cookie: {
maxAge: 30000,
secure: false,
httpOnly: true,
domain: config.get('app.domainecookie')
}
});
app.use(sessionMiddleware);
I'm making periodically calls to my server, and I see the "expires" parameter of my cookie updates correctly, pushing the 30000 limit further. But, for some reason, the session is destroyed and I get another session ID, again for 30000.
Here is what I use to check my session ID:
app.use((req, res, next) => {
console.log(`CURRENT SESSION: ${req.session.id}`);
})
When I check in my browser, I see that even if the cookie expiration date changes on the server, it doesn't change in the client (browser). Is there a way to update the expiration date client-side?
I thought I could resend the cookie like this:
app.use((req, res, next) => {
console.log(`CURRENT SESSION: ${req.session.id}`);
res.cookie('connect.sid', req.sessionID, req.session.cookie);
})
But it keeps changing the cookie to another one, sometimes with the value of a correct sessionID, sometimes with 's:' followed by a value of another cookie.
I thought I could send the 'connect.sid' cookie from my client to the server to update it, but as it's a signed cookie I would have to use the same secret client-side and that is clearly not possible.
What am I doing wrong here? I thought setting "resave" to true wouldn't destroy the session.
Waw, that was not as easy as it should be. I finally found what to do: the problem was I had to sign the cookie with the same secret as I initialized it. For that, I had to install the cookie-signature
package.
npm i --save cookie-signature
I create a signature function like this:
const signature = require('cookie-signature').sign;
Then, in my middleware app.use
function, I simply had to write these lines (look at the s:
which is added for some reason...):
const signedSessionId = signature(req.sessionID, SESSIONSECRET);
res.cookie('connect.sid', `s:${signedSessionId}`, req.session.cookie);
Like this, the expiration date of the cookie client-side is pushed further, like it is in the server-side.
Note: it's very strange that the connect.sid
cookie doesn't update automatically client-side even though it has been updated server-side. I don't see the point of using resave: true
if the information is not passed to the client. If I misread the documentation and there is actually a native way to do it, I'd be glad to know the way.