req.session.user is deleted while user is active












2














I set the session timeout to 30 minutes. While I am still active, req.session.user is deleted after 30 minutes. However, the session is still alive. Here's my config (i'm using express-session and passport.js):



app.use(session({
store: new RedisStore({client: <my client>, disableTTL: true}),
secret: <some_secret>,
resave: true,
saveUninitialized: false,
cookie: {maxAge: 1800000}
}));

app.use(passport.initialize());
app.use(passport.session());

// Are these serializer/deserializer needed?
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});


In login:



router.post('/login', (req, res, next) => {
passport.authenticate('ldapauth', {session: false}, (err, user, info) => {
...
if (user) {
req.session.user = {email: req.body.username};
}
next();
})(req, res);
});


The verify code is like this:



isLoggedIn() {
if (req.session && req.session.user) {
return true;
}
return false;
}


I set the req.session.user to some object after I successfully logged in.



So, after 30 minutes, req.session.user is deleted, but req.session is still there and keeps on incrementing the expiry date since I am still actively working on the page.



Why is req.session.user deleted after 30 minutes? I thought passport rides on the session by express?



* UPDATE *
At first, I thought the expiry is incrementing, but it's not. Previously, I set resave: false. Then when I log the session, the expiry is always the same:



Session {
cookie:
{ path: '/', _expires: <some date>.... }
user:
{ email: <the one i set before>, sessionId: <some id> } }


Then after 30 minutes, the user is deleted. Only at this point, the expiry begins incrementing.



Session {
cookie:
{ path: '/', _expires: <some date>.... }


Then I read something about the touch method that express-session calls. The documentation said that if the store implements this touch method, then it's ok to set the resave: false. So, thinking that redis may not be implementing this method, I tried setting resave: true. Then when I log the session, I noticed that the expiry is now incrementing, compared to the previous that it only increments after user is deleted. However, after 30 minutes, again the user key is deleted.



Then with niry's suggestion, I set the disableTTL: true. Again, the same thing happened.



In redis, I try to mget the key. Before the 30 minutes end, the expiry in redis is incrementing:



127.0.0.1:6379> mget sess:<some id>


1) "{"cookie":{"originalMaxAge":1800000,"expires":"2018-11-15T06:04:26.994Z","httpOnly":true,"path":"/"},"user":{"email":"test@email.com","sessionId":"some session id"}}"



Then after 30 minutes, I looked at redis, the session key is still there but it stopped incrementing the expiry. While, req.session still increments the expiry but with the user property deleted.










share|improve this question
























  • Please post the redis options. I suspect you set the expiration on the data.
    – niry
    Nov 11 at 8:29










  • I didn't set any expiration on Redis. In the options i only provide the client to connect to. Besides, even when i encountered the timeout, the session id remains in redis.
    – iPhoneJavaDev
    Nov 11 at 10:42










  • Just to clarify, with "encountered the timeout", I mean the req.session.user that I set got deleted after 30 minutes of still being active. I'm thinking there's something going on with passport, maybe, i'm not sure.
    – iPhoneJavaDev
    Nov 11 at 11:28
















2














I set the session timeout to 30 minutes. While I am still active, req.session.user is deleted after 30 minutes. However, the session is still alive. Here's my config (i'm using express-session and passport.js):



app.use(session({
store: new RedisStore({client: <my client>, disableTTL: true}),
secret: <some_secret>,
resave: true,
saveUninitialized: false,
cookie: {maxAge: 1800000}
}));

app.use(passport.initialize());
app.use(passport.session());

// Are these serializer/deserializer needed?
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});


In login:



router.post('/login', (req, res, next) => {
passport.authenticate('ldapauth', {session: false}, (err, user, info) => {
...
if (user) {
req.session.user = {email: req.body.username};
}
next();
})(req, res);
});


The verify code is like this:



isLoggedIn() {
if (req.session && req.session.user) {
return true;
}
return false;
}


I set the req.session.user to some object after I successfully logged in.



So, after 30 minutes, req.session.user is deleted, but req.session is still there and keeps on incrementing the expiry date since I am still actively working on the page.



Why is req.session.user deleted after 30 minutes? I thought passport rides on the session by express?



* UPDATE *
At first, I thought the expiry is incrementing, but it's not. Previously, I set resave: false. Then when I log the session, the expiry is always the same:



Session {
cookie:
{ path: '/', _expires: <some date>.... }
user:
{ email: <the one i set before>, sessionId: <some id> } }


Then after 30 minutes, the user is deleted. Only at this point, the expiry begins incrementing.



Session {
cookie:
{ path: '/', _expires: <some date>.... }


Then I read something about the touch method that express-session calls. The documentation said that if the store implements this touch method, then it's ok to set the resave: false. So, thinking that redis may not be implementing this method, I tried setting resave: true. Then when I log the session, I noticed that the expiry is now incrementing, compared to the previous that it only increments after user is deleted. However, after 30 minutes, again the user key is deleted.



Then with niry's suggestion, I set the disableTTL: true. Again, the same thing happened.



In redis, I try to mget the key. Before the 30 minutes end, the expiry in redis is incrementing:



127.0.0.1:6379> mget sess:<some id>


1) "{"cookie":{"originalMaxAge":1800000,"expires":"2018-11-15T06:04:26.994Z","httpOnly":true,"path":"/"},"user":{"email":"test@email.com","sessionId":"some session id"}}"



Then after 30 minutes, I looked at redis, the session key is still there but it stopped incrementing the expiry. While, req.session still increments the expiry but with the user property deleted.










share|improve this question
























  • Please post the redis options. I suspect you set the expiration on the data.
    – niry
    Nov 11 at 8:29










  • I didn't set any expiration on Redis. In the options i only provide the client to connect to. Besides, even when i encountered the timeout, the session id remains in redis.
    – iPhoneJavaDev
    Nov 11 at 10:42










  • Just to clarify, with "encountered the timeout", I mean the req.session.user that I set got deleted after 30 minutes of still being active. I'm thinking there's something going on with passport, maybe, i'm not sure.
    – iPhoneJavaDev
    Nov 11 at 11:28














2












2








2


2





I set the session timeout to 30 minutes. While I am still active, req.session.user is deleted after 30 minutes. However, the session is still alive. Here's my config (i'm using express-session and passport.js):



app.use(session({
store: new RedisStore({client: <my client>, disableTTL: true}),
secret: <some_secret>,
resave: true,
saveUninitialized: false,
cookie: {maxAge: 1800000}
}));

app.use(passport.initialize());
app.use(passport.session());

// Are these serializer/deserializer needed?
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});


In login:



router.post('/login', (req, res, next) => {
passport.authenticate('ldapauth', {session: false}, (err, user, info) => {
...
if (user) {
req.session.user = {email: req.body.username};
}
next();
})(req, res);
});


The verify code is like this:



isLoggedIn() {
if (req.session && req.session.user) {
return true;
}
return false;
}


I set the req.session.user to some object after I successfully logged in.



So, after 30 minutes, req.session.user is deleted, but req.session is still there and keeps on incrementing the expiry date since I am still actively working on the page.



Why is req.session.user deleted after 30 minutes? I thought passport rides on the session by express?



* UPDATE *
At first, I thought the expiry is incrementing, but it's not. Previously, I set resave: false. Then when I log the session, the expiry is always the same:



Session {
cookie:
{ path: '/', _expires: <some date>.... }
user:
{ email: <the one i set before>, sessionId: <some id> } }


Then after 30 minutes, the user is deleted. Only at this point, the expiry begins incrementing.



Session {
cookie:
{ path: '/', _expires: <some date>.... }


Then I read something about the touch method that express-session calls. The documentation said that if the store implements this touch method, then it's ok to set the resave: false. So, thinking that redis may not be implementing this method, I tried setting resave: true. Then when I log the session, I noticed that the expiry is now incrementing, compared to the previous that it only increments after user is deleted. However, after 30 minutes, again the user key is deleted.



Then with niry's suggestion, I set the disableTTL: true. Again, the same thing happened.



In redis, I try to mget the key. Before the 30 minutes end, the expiry in redis is incrementing:



127.0.0.1:6379> mget sess:<some id>


1) "{"cookie":{"originalMaxAge":1800000,"expires":"2018-11-15T06:04:26.994Z","httpOnly":true,"path":"/"},"user":{"email":"test@email.com","sessionId":"some session id"}}"



Then after 30 minutes, I looked at redis, the session key is still there but it stopped incrementing the expiry. While, req.session still increments the expiry but with the user property deleted.










share|improve this question















I set the session timeout to 30 minutes. While I am still active, req.session.user is deleted after 30 minutes. However, the session is still alive. Here's my config (i'm using express-session and passport.js):



app.use(session({
store: new RedisStore({client: <my client>, disableTTL: true}),
secret: <some_secret>,
resave: true,
saveUninitialized: false,
cookie: {maxAge: 1800000}
}));

app.use(passport.initialize());
app.use(passport.session());

// Are these serializer/deserializer needed?
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});


In login:



router.post('/login', (req, res, next) => {
passport.authenticate('ldapauth', {session: false}, (err, user, info) => {
...
if (user) {
req.session.user = {email: req.body.username};
}
next();
})(req, res);
});


The verify code is like this:



isLoggedIn() {
if (req.session && req.session.user) {
return true;
}
return false;
}


I set the req.session.user to some object after I successfully logged in.



So, after 30 minutes, req.session.user is deleted, but req.session is still there and keeps on incrementing the expiry date since I am still actively working on the page.



Why is req.session.user deleted after 30 minutes? I thought passport rides on the session by express?



* UPDATE *
At first, I thought the expiry is incrementing, but it's not. Previously, I set resave: false. Then when I log the session, the expiry is always the same:



Session {
cookie:
{ path: '/', _expires: <some date>.... }
user:
{ email: <the one i set before>, sessionId: <some id> } }


Then after 30 minutes, the user is deleted. Only at this point, the expiry begins incrementing.



Session {
cookie:
{ path: '/', _expires: <some date>.... }


Then I read something about the touch method that express-session calls. The documentation said that if the store implements this touch method, then it's ok to set the resave: false. So, thinking that redis may not be implementing this method, I tried setting resave: true. Then when I log the session, I noticed that the expiry is now incrementing, compared to the previous that it only increments after user is deleted. However, after 30 minutes, again the user key is deleted.



Then with niry's suggestion, I set the disableTTL: true. Again, the same thing happened.



In redis, I try to mget the key. Before the 30 minutes end, the expiry in redis is incrementing:



127.0.0.1:6379> mget sess:<some id>


1) "{"cookie":{"originalMaxAge":1800000,"expires":"2018-11-15T06:04:26.994Z","httpOnly":true,"path":"/"},"user":{"email":"test@email.com","sessionId":"some session id"}}"



Then after 30 minutes, I looked at redis, the session key is still there but it stopped incrementing the expiry. While, req.session still increments the expiry but with the user property deleted.







node.js passport.js node-redis






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 at 6:10

























asked Nov 8 at 9:34









iPhoneJavaDev

2312730




2312730












  • Please post the redis options. I suspect you set the expiration on the data.
    – niry
    Nov 11 at 8:29










  • I didn't set any expiration on Redis. In the options i only provide the client to connect to. Besides, even when i encountered the timeout, the session id remains in redis.
    – iPhoneJavaDev
    Nov 11 at 10:42










  • Just to clarify, with "encountered the timeout", I mean the req.session.user that I set got deleted after 30 minutes of still being active. I'm thinking there's something going on with passport, maybe, i'm not sure.
    – iPhoneJavaDev
    Nov 11 at 11:28


















  • Please post the redis options. I suspect you set the expiration on the data.
    – niry
    Nov 11 at 8:29










  • I didn't set any expiration on Redis. In the options i only provide the client to connect to. Besides, even when i encountered the timeout, the session id remains in redis.
    – iPhoneJavaDev
    Nov 11 at 10:42










  • Just to clarify, with "encountered the timeout", I mean the req.session.user that I set got deleted after 30 minutes of still being active. I'm thinking there's something going on with passport, maybe, i'm not sure.
    – iPhoneJavaDev
    Nov 11 at 11:28
















Please post the redis options. I suspect you set the expiration on the data.
– niry
Nov 11 at 8:29




Please post the redis options. I suspect you set the expiration on the data.
– niry
Nov 11 at 8:29












I didn't set any expiration on Redis. In the options i only provide the client to connect to. Besides, even when i encountered the timeout, the session id remains in redis.
– iPhoneJavaDev
Nov 11 at 10:42




I didn't set any expiration on Redis. In the options i only provide the client to connect to. Besides, even when i encountered the timeout, the session id remains in redis.
– iPhoneJavaDev
Nov 11 at 10:42












Just to clarify, with "encountered the timeout", I mean the req.session.user that I set got deleted after 30 minutes of still being active. I'm thinking there's something going on with passport, maybe, i'm not sure.
– iPhoneJavaDev
Nov 11 at 11:28




Just to clarify, with "encountered the timeout", I mean the req.session.user that I set got deleted after 30 minutes of still being active. I'm thinking there's something going on with passport, maybe, i'm not sure.
– iPhoneJavaDev
Nov 11 at 11:28












1 Answer
1






active

oldest

votes


















0





+50










Why is req.session.user deleted after 30 minutes?




Because the maxAge option of cookie is set to 1800000 ms which is 30 minutes. So the browser ( or whatever client you are using ) will delete the cookie after 30 minutes.



A session is some information you want to persist over subsequent requests. Generally, a session has an ID(sessionID) and associated payload. When you do req.session = { ... }, the express-session middleware would take the object, generate an ID and save it in the store you specified. (RedisStore in your case). So now your "database" has the mapping of sessionID and the payload.



Cookies are something that once sent from the server, they would be forwarded every-time to that server (to that domain) for each subsequent request until they are expired. Note that once the cookie is received, it is the client's job to manage it. The generated sessionID along with the signature is sent to the client in the cookie.



Once the cookie is saved on your client. It will forwarded with the next request.
When your express-session middleware sees the cookie, it extracts the sessionID from the cookie, and try to look for the corresponding payload in the store (RedisStore in your case). The payload is then set to req.session along with other information.



Once the expiry time is reached, the client will delete the cookie. Thus, request from that client would not have the cookie. Because the cookie is not there, the express-session will not be able to set the req.session and you would think that the user is logged out. Note that, the store still contains the sessionID, payload mapping which will be deleted according to ttl config of store.





I think the confusion arose in the first place is because of session.cookie field. session.cookie will always be there because of the express-session middleware.



If you want to see the actual cookies received in the request, try cookie-parser middleware.





I am attaching sample code to tinker. The set-cookie endpoint will set the cookie which expires in 20 seconds. get-cookie endpoint will get the cookie and session data.



Hope this will help!



const express = require("express");
const session = require("express-session");
const cookieParser = require("cookie-parser");
const FileStore = require("session-file-store")(session);
const path = require("path");

const app = express();

app.use(express.json());

app.use(cookieParser());
app.use(
session({
secret: "top secret!",
resave: false,
rolling: true,
saveUninitialized: false,
cookie: {
maxAge: 20 * 1000
},
name: "demo",
store: new FileStore({
path: path.join(__dirname, "../sessions"),
retries: 1,
fileExtension: ".json"
})
})
);

app.use("/set-cookie", (req, res) => {
req.session.payload = { foo: "bar", timestamp: new Date().toISOString() };
res.json({ message: "done" });
});

app.use("/get-cookie", (req, res) => {
res.json({
sessionID: req.sessionID,
session: req.session,
cookies: req.cookies,
timestamp: new Date().toISOString()
});
});

app.listen(3000, err => {
if (err) {
throw err;
}
console.log("demo app listening on port 3000");
});




UPDATE
Based on the comments, what you are looking for the rolling option. Once you set the rolling: true in express-session, the session will be updated for every request. And user will be logged out after maxAge IDEAL time.



I have updated the code.






share|improve this answer























  • Sorry but I got more confused. I think I understand the part of session cookie between the client and the server. The thing is, the user is still active and the expiry time is incrementing.
    – iPhoneJavaDev
    Nov 15 at 7:27










  • What do you exactly mean by "the user is still active"?. As I said, the expiry time is the time when the cookie would expire if it is set in that request
    – Anand Undavia
    Nov 15 at 7:29










  • So, you would always see expires at = current time + maxAge no matter the cookie is actually set or not. Try it out
    – Anand Undavia
    Nov 15 at 7:30










  • My goal is when user becomes idle for 30 minutes, the session will expire. So when the user try to call an api, i'll throw an error since his session is already expired. But since the user is still activly calling the api within 30 minutes, i am expecting the session expiry will increment. For example, the user has been idle for 5 minutes, so the remaining time before session expires is 25 minutes. Then user calls an api and the expiry time resets to 30 minutes. Looking at redis and req.session, it seems incrementing while user is active which is what i expect.
    – iPhoneJavaDev
    Nov 15 at 7:51










  • Ahh alright now I understand it properly. I would update the answer accordingly, meanwhile, you might want to update the question with that details too!
    – Anand Undavia
    Nov 15 at 8:07











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53204922%2freq-session-user-is-deleted-while-user-is-active%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0





+50










Why is req.session.user deleted after 30 minutes?




Because the maxAge option of cookie is set to 1800000 ms which is 30 minutes. So the browser ( or whatever client you are using ) will delete the cookie after 30 minutes.



A session is some information you want to persist over subsequent requests. Generally, a session has an ID(sessionID) and associated payload. When you do req.session = { ... }, the express-session middleware would take the object, generate an ID and save it in the store you specified. (RedisStore in your case). So now your "database" has the mapping of sessionID and the payload.



Cookies are something that once sent from the server, they would be forwarded every-time to that server (to that domain) for each subsequent request until they are expired. Note that once the cookie is received, it is the client's job to manage it. The generated sessionID along with the signature is sent to the client in the cookie.



Once the cookie is saved on your client. It will forwarded with the next request.
When your express-session middleware sees the cookie, it extracts the sessionID from the cookie, and try to look for the corresponding payload in the store (RedisStore in your case). The payload is then set to req.session along with other information.



Once the expiry time is reached, the client will delete the cookie. Thus, request from that client would not have the cookie. Because the cookie is not there, the express-session will not be able to set the req.session and you would think that the user is logged out. Note that, the store still contains the sessionID, payload mapping which will be deleted according to ttl config of store.





I think the confusion arose in the first place is because of session.cookie field. session.cookie will always be there because of the express-session middleware.



If you want to see the actual cookies received in the request, try cookie-parser middleware.





I am attaching sample code to tinker. The set-cookie endpoint will set the cookie which expires in 20 seconds. get-cookie endpoint will get the cookie and session data.



Hope this will help!



const express = require("express");
const session = require("express-session");
const cookieParser = require("cookie-parser");
const FileStore = require("session-file-store")(session);
const path = require("path");

const app = express();

app.use(express.json());

app.use(cookieParser());
app.use(
session({
secret: "top secret!",
resave: false,
rolling: true,
saveUninitialized: false,
cookie: {
maxAge: 20 * 1000
},
name: "demo",
store: new FileStore({
path: path.join(__dirname, "../sessions"),
retries: 1,
fileExtension: ".json"
})
})
);

app.use("/set-cookie", (req, res) => {
req.session.payload = { foo: "bar", timestamp: new Date().toISOString() };
res.json({ message: "done" });
});

app.use("/get-cookie", (req, res) => {
res.json({
sessionID: req.sessionID,
session: req.session,
cookies: req.cookies,
timestamp: new Date().toISOString()
});
});

app.listen(3000, err => {
if (err) {
throw err;
}
console.log("demo app listening on port 3000");
});




UPDATE
Based on the comments, what you are looking for the rolling option. Once you set the rolling: true in express-session, the session will be updated for every request. And user will be logged out after maxAge IDEAL time.



I have updated the code.






share|improve this answer























  • Sorry but I got more confused. I think I understand the part of session cookie between the client and the server. The thing is, the user is still active and the expiry time is incrementing.
    – iPhoneJavaDev
    Nov 15 at 7:27










  • What do you exactly mean by "the user is still active"?. As I said, the expiry time is the time when the cookie would expire if it is set in that request
    – Anand Undavia
    Nov 15 at 7:29










  • So, you would always see expires at = current time + maxAge no matter the cookie is actually set or not. Try it out
    – Anand Undavia
    Nov 15 at 7:30










  • My goal is when user becomes idle for 30 minutes, the session will expire. So when the user try to call an api, i'll throw an error since his session is already expired. But since the user is still activly calling the api within 30 minutes, i am expecting the session expiry will increment. For example, the user has been idle for 5 minutes, so the remaining time before session expires is 25 minutes. Then user calls an api and the expiry time resets to 30 minutes. Looking at redis and req.session, it seems incrementing while user is active which is what i expect.
    – iPhoneJavaDev
    Nov 15 at 7:51










  • Ahh alright now I understand it properly. I would update the answer accordingly, meanwhile, you might want to update the question with that details too!
    – Anand Undavia
    Nov 15 at 8:07
















0





+50










Why is req.session.user deleted after 30 minutes?




Because the maxAge option of cookie is set to 1800000 ms which is 30 minutes. So the browser ( or whatever client you are using ) will delete the cookie after 30 minutes.



A session is some information you want to persist over subsequent requests. Generally, a session has an ID(sessionID) and associated payload. When you do req.session = { ... }, the express-session middleware would take the object, generate an ID and save it in the store you specified. (RedisStore in your case). So now your "database" has the mapping of sessionID and the payload.



Cookies are something that once sent from the server, they would be forwarded every-time to that server (to that domain) for each subsequent request until they are expired. Note that once the cookie is received, it is the client's job to manage it. The generated sessionID along with the signature is sent to the client in the cookie.



Once the cookie is saved on your client. It will forwarded with the next request.
When your express-session middleware sees the cookie, it extracts the sessionID from the cookie, and try to look for the corresponding payload in the store (RedisStore in your case). The payload is then set to req.session along with other information.



Once the expiry time is reached, the client will delete the cookie. Thus, request from that client would not have the cookie. Because the cookie is not there, the express-session will not be able to set the req.session and you would think that the user is logged out. Note that, the store still contains the sessionID, payload mapping which will be deleted according to ttl config of store.





I think the confusion arose in the first place is because of session.cookie field. session.cookie will always be there because of the express-session middleware.



If you want to see the actual cookies received in the request, try cookie-parser middleware.





I am attaching sample code to tinker. The set-cookie endpoint will set the cookie which expires in 20 seconds. get-cookie endpoint will get the cookie and session data.



Hope this will help!



const express = require("express");
const session = require("express-session");
const cookieParser = require("cookie-parser");
const FileStore = require("session-file-store")(session);
const path = require("path");

const app = express();

app.use(express.json());

app.use(cookieParser());
app.use(
session({
secret: "top secret!",
resave: false,
rolling: true,
saveUninitialized: false,
cookie: {
maxAge: 20 * 1000
},
name: "demo",
store: new FileStore({
path: path.join(__dirname, "../sessions"),
retries: 1,
fileExtension: ".json"
})
})
);

app.use("/set-cookie", (req, res) => {
req.session.payload = { foo: "bar", timestamp: new Date().toISOString() };
res.json({ message: "done" });
});

app.use("/get-cookie", (req, res) => {
res.json({
sessionID: req.sessionID,
session: req.session,
cookies: req.cookies,
timestamp: new Date().toISOString()
});
});

app.listen(3000, err => {
if (err) {
throw err;
}
console.log("demo app listening on port 3000");
});




UPDATE
Based on the comments, what you are looking for the rolling option. Once you set the rolling: true in express-session, the session will be updated for every request. And user will be logged out after maxAge IDEAL time.



I have updated the code.






share|improve this answer























  • Sorry but I got more confused. I think I understand the part of session cookie between the client and the server. The thing is, the user is still active and the expiry time is incrementing.
    – iPhoneJavaDev
    Nov 15 at 7:27










  • What do you exactly mean by "the user is still active"?. As I said, the expiry time is the time when the cookie would expire if it is set in that request
    – Anand Undavia
    Nov 15 at 7:29










  • So, you would always see expires at = current time + maxAge no matter the cookie is actually set or not. Try it out
    – Anand Undavia
    Nov 15 at 7:30










  • My goal is when user becomes idle for 30 minutes, the session will expire. So when the user try to call an api, i'll throw an error since his session is already expired. But since the user is still activly calling the api within 30 minutes, i am expecting the session expiry will increment. For example, the user has been idle for 5 minutes, so the remaining time before session expires is 25 minutes. Then user calls an api and the expiry time resets to 30 minutes. Looking at redis and req.session, it seems incrementing while user is active which is what i expect.
    – iPhoneJavaDev
    Nov 15 at 7:51










  • Ahh alright now I understand it properly. I would update the answer accordingly, meanwhile, you might want to update the question with that details too!
    – Anand Undavia
    Nov 15 at 8:07














0





+50







0





+50



0




+50





Why is req.session.user deleted after 30 minutes?




Because the maxAge option of cookie is set to 1800000 ms which is 30 minutes. So the browser ( or whatever client you are using ) will delete the cookie after 30 minutes.



A session is some information you want to persist over subsequent requests. Generally, a session has an ID(sessionID) and associated payload. When you do req.session = { ... }, the express-session middleware would take the object, generate an ID and save it in the store you specified. (RedisStore in your case). So now your "database" has the mapping of sessionID and the payload.



Cookies are something that once sent from the server, they would be forwarded every-time to that server (to that domain) for each subsequent request until they are expired. Note that once the cookie is received, it is the client's job to manage it. The generated sessionID along with the signature is sent to the client in the cookie.



Once the cookie is saved on your client. It will forwarded with the next request.
When your express-session middleware sees the cookie, it extracts the sessionID from the cookie, and try to look for the corresponding payload in the store (RedisStore in your case). The payload is then set to req.session along with other information.



Once the expiry time is reached, the client will delete the cookie. Thus, request from that client would not have the cookie. Because the cookie is not there, the express-session will not be able to set the req.session and you would think that the user is logged out. Note that, the store still contains the sessionID, payload mapping which will be deleted according to ttl config of store.





I think the confusion arose in the first place is because of session.cookie field. session.cookie will always be there because of the express-session middleware.



If you want to see the actual cookies received in the request, try cookie-parser middleware.





I am attaching sample code to tinker. The set-cookie endpoint will set the cookie which expires in 20 seconds. get-cookie endpoint will get the cookie and session data.



Hope this will help!



const express = require("express");
const session = require("express-session");
const cookieParser = require("cookie-parser");
const FileStore = require("session-file-store")(session);
const path = require("path");

const app = express();

app.use(express.json());

app.use(cookieParser());
app.use(
session({
secret: "top secret!",
resave: false,
rolling: true,
saveUninitialized: false,
cookie: {
maxAge: 20 * 1000
},
name: "demo",
store: new FileStore({
path: path.join(__dirname, "../sessions"),
retries: 1,
fileExtension: ".json"
})
})
);

app.use("/set-cookie", (req, res) => {
req.session.payload = { foo: "bar", timestamp: new Date().toISOString() };
res.json({ message: "done" });
});

app.use("/get-cookie", (req, res) => {
res.json({
sessionID: req.sessionID,
session: req.session,
cookies: req.cookies,
timestamp: new Date().toISOString()
});
});

app.listen(3000, err => {
if (err) {
throw err;
}
console.log("demo app listening on port 3000");
});




UPDATE
Based on the comments, what you are looking for the rolling option. Once you set the rolling: true in express-session, the session will be updated for every request. And user will be logged out after maxAge IDEAL time.



I have updated the code.






share|improve this answer















Why is req.session.user deleted after 30 minutes?




Because the maxAge option of cookie is set to 1800000 ms which is 30 minutes. So the browser ( or whatever client you are using ) will delete the cookie after 30 minutes.



A session is some information you want to persist over subsequent requests. Generally, a session has an ID(sessionID) and associated payload. When you do req.session = { ... }, the express-session middleware would take the object, generate an ID and save it in the store you specified. (RedisStore in your case). So now your "database" has the mapping of sessionID and the payload.



Cookies are something that once sent from the server, they would be forwarded every-time to that server (to that domain) for each subsequent request until they are expired. Note that once the cookie is received, it is the client's job to manage it. The generated sessionID along with the signature is sent to the client in the cookie.



Once the cookie is saved on your client. It will forwarded with the next request.
When your express-session middleware sees the cookie, it extracts the sessionID from the cookie, and try to look for the corresponding payload in the store (RedisStore in your case). The payload is then set to req.session along with other information.



Once the expiry time is reached, the client will delete the cookie. Thus, request from that client would not have the cookie. Because the cookie is not there, the express-session will not be able to set the req.session and you would think that the user is logged out. Note that, the store still contains the sessionID, payload mapping which will be deleted according to ttl config of store.





I think the confusion arose in the first place is because of session.cookie field. session.cookie will always be there because of the express-session middleware.



If you want to see the actual cookies received in the request, try cookie-parser middleware.





I am attaching sample code to tinker. The set-cookie endpoint will set the cookie which expires in 20 seconds. get-cookie endpoint will get the cookie and session data.



Hope this will help!



const express = require("express");
const session = require("express-session");
const cookieParser = require("cookie-parser");
const FileStore = require("session-file-store")(session);
const path = require("path");

const app = express();

app.use(express.json());

app.use(cookieParser());
app.use(
session({
secret: "top secret!",
resave: false,
rolling: true,
saveUninitialized: false,
cookie: {
maxAge: 20 * 1000
},
name: "demo",
store: new FileStore({
path: path.join(__dirname, "../sessions"),
retries: 1,
fileExtension: ".json"
})
})
);

app.use("/set-cookie", (req, res) => {
req.session.payload = { foo: "bar", timestamp: new Date().toISOString() };
res.json({ message: "done" });
});

app.use("/get-cookie", (req, res) => {
res.json({
sessionID: req.sessionID,
session: req.session,
cookies: req.cookies,
timestamp: new Date().toISOString()
});
});

app.listen(3000, err => {
if (err) {
throw err;
}
console.log("demo app listening on port 3000");
});




UPDATE
Based on the comments, what you are looking for the rolling option. Once you set the rolling: true in express-session, the session will be updated for every request. And user will be logged out after maxAge IDEAL time.



I have updated the code.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 15 at 8:13

























answered Nov 15 at 6:40









Anand Undavia

1,6001923




1,6001923












  • Sorry but I got more confused. I think I understand the part of session cookie between the client and the server. The thing is, the user is still active and the expiry time is incrementing.
    – iPhoneJavaDev
    Nov 15 at 7:27










  • What do you exactly mean by "the user is still active"?. As I said, the expiry time is the time when the cookie would expire if it is set in that request
    – Anand Undavia
    Nov 15 at 7:29










  • So, you would always see expires at = current time + maxAge no matter the cookie is actually set or not. Try it out
    – Anand Undavia
    Nov 15 at 7:30










  • My goal is when user becomes idle for 30 minutes, the session will expire. So when the user try to call an api, i'll throw an error since his session is already expired. But since the user is still activly calling the api within 30 minutes, i am expecting the session expiry will increment. For example, the user has been idle for 5 minutes, so the remaining time before session expires is 25 minutes. Then user calls an api and the expiry time resets to 30 minutes. Looking at redis and req.session, it seems incrementing while user is active which is what i expect.
    – iPhoneJavaDev
    Nov 15 at 7:51










  • Ahh alright now I understand it properly. I would update the answer accordingly, meanwhile, you might want to update the question with that details too!
    – Anand Undavia
    Nov 15 at 8:07


















  • Sorry but I got more confused. I think I understand the part of session cookie between the client and the server. The thing is, the user is still active and the expiry time is incrementing.
    – iPhoneJavaDev
    Nov 15 at 7:27










  • What do you exactly mean by "the user is still active"?. As I said, the expiry time is the time when the cookie would expire if it is set in that request
    – Anand Undavia
    Nov 15 at 7:29










  • So, you would always see expires at = current time + maxAge no matter the cookie is actually set or not. Try it out
    – Anand Undavia
    Nov 15 at 7:30










  • My goal is when user becomes idle for 30 minutes, the session will expire. So when the user try to call an api, i'll throw an error since his session is already expired. But since the user is still activly calling the api within 30 minutes, i am expecting the session expiry will increment. For example, the user has been idle for 5 minutes, so the remaining time before session expires is 25 minutes. Then user calls an api and the expiry time resets to 30 minutes. Looking at redis and req.session, it seems incrementing while user is active which is what i expect.
    – iPhoneJavaDev
    Nov 15 at 7:51










  • Ahh alright now I understand it properly. I would update the answer accordingly, meanwhile, you might want to update the question with that details too!
    – Anand Undavia
    Nov 15 at 8:07
















Sorry but I got more confused. I think I understand the part of session cookie between the client and the server. The thing is, the user is still active and the expiry time is incrementing.
– iPhoneJavaDev
Nov 15 at 7:27




Sorry but I got more confused. I think I understand the part of session cookie between the client and the server. The thing is, the user is still active and the expiry time is incrementing.
– iPhoneJavaDev
Nov 15 at 7:27












What do you exactly mean by "the user is still active"?. As I said, the expiry time is the time when the cookie would expire if it is set in that request
– Anand Undavia
Nov 15 at 7:29




What do you exactly mean by "the user is still active"?. As I said, the expiry time is the time when the cookie would expire if it is set in that request
– Anand Undavia
Nov 15 at 7:29












So, you would always see expires at = current time + maxAge no matter the cookie is actually set or not. Try it out
– Anand Undavia
Nov 15 at 7:30




So, you would always see expires at = current time + maxAge no matter the cookie is actually set or not. Try it out
– Anand Undavia
Nov 15 at 7:30












My goal is when user becomes idle for 30 minutes, the session will expire. So when the user try to call an api, i'll throw an error since his session is already expired. But since the user is still activly calling the api within 30 minutes, i am expecting the session expiry will increment. For example, the user has been idle for 5 minutes, so the remaining time before session expires is 25 minutes. Then user calls an api and the expiry time resets to 30 minutes. Looking at redis and req.session, it seems incrementing while user is active which is what i expect.
– iPhoneJavaDev
Nov 15 at 7:51




My goal is when user becomes idle for 30 minutes, the session will expire. So when the user try to call an api, i'll throw an error since his session is already expired. But since the user is still activly calling the api within 30 minutes, i am expecting the session expiry will increment. For example, the user has been idle for 5 minutes, so the remaining time before session expires is 25 minutes. Then user calls an api and the expiry time resets to 30 minutes. Looking at redis and req.session, it seems incrementing while user is active which is what i expect.
– iPhoneJavaDev
Nov 15 at 7:51












Ahh alright now I understand it properly. I would update the answer accordingly, meanwhile, you might want to update the question with that details too!
– Anand Undavia
Nov 15 at 8:07




Ahh alright now I understand it properly. I would update the answer accordingly, meanwhile, you might want to update the question with that details too!
– Anand Undavia
Nov 15 at 8:07


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53204922%2freq-session-user-is-deleted-while-user-is-active%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Tangent Lines Diagram Along Smooth Curve

Yusuf al-Mu'taman ibn Hud

Zucchini