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.
CodePudding user response:
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.
CodePudding user response:
If you want to handle your user' session with a cookie, using express-session and connect-redis, you can normally follow this example
const express=require('express');
const app=express();
const session = require('express-session')
const Redis = require('ioredis');
const clientRedis = new Redis();
const RedisStore = require('connect-redis')(session);
const SESSIONSECRET = "my-secret";
const sessionMiddleware = session({
store: new RedisStore({
client: clientRedis,
}),
secret: SESSIONSECRET,
saveUninitialized: true,
resave:true,
cookie: {
maxAge: 60000,
secure: false,
httpOnly: true,
domain:"localhost"
}
});
app.listen(3000);
app.use(sessionMiddleware);
app.get("/",(req,res)=>{
console.log(req.session.id)
req.session.lastAccess=new Date().toISOString();
res.json({"hello":"session"})
})
The node-session already parse the cookies, so you don't need an other package for it. It also put everything in the response header automatically, so no need to set the res.cookie yourself.
You don't have anything else to do from what I can tell. The TTL of the key in redis will be reset/update at the max age of the cookie, here 1 minute, and you should see the expiration date of the cookie update in the browser too.
Maybe the custom middleware you made hijacked the cookie value send in the response
Tell me if it helps you. If something still feels strange to you, tell me in comment and I will update my response.
Cheers !