req.session.user is deleted while user is active
up vote
2
down vote
favorite
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
add a comment |
up vote
2
down vote
favorite
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
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
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
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
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
node.js passport.js node-redis
edited Nov 15 at 6:10
asked Nov 8 at 9:34
iPhoneJavaDev
1722730
1722730
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
accepted
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.
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 seeexpires 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
|
show 3 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
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.
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 seeexpires 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
|
show 3 more comments
up vote
0
down vote
accepted
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.
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 seeexpires 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
|
show 3 more comments
up vote
0
down vote
accepted
up vote
0
down vote
accepted
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.
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.
edited Nov 15 at 8:13
answered Nov 15 at 6:40
Anand Undavia
1,575922
1,575922
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 seeexpires 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
|
show 3 more comments
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 seeexpires 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
|
show 3 more comments
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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