How can I set presistent cookies on node.js with express-session? - node.js

I want to create preistent cookies so that the user of my app doesn't have to login every time he enters the web. But instead, just require log in if he/she ever logs out. Basically, I would like to know if there is a way to set maxAge to infinity(equivalent) and the cookies to persist even if the user closes the browser.
Here is my code:
app.use(expressSession({
secret: '',
resave: false,
saveUninitialized: false,
cookie: {
secure: false,
expires: false,
}
}))

Based on the standards, you cannot set it to infinity:
Max-Age=value
OPTIONAL. The value of the Max-Age attribute is delta-seconds,
the lifetime of the cookie in seconds, a decimal non-negative
integer. To handle cached cookies correctly, a client SHOULD
calculate the age of the cookie according to the age calculation
rules in the HTTP/1.1 specification [RFC2616]. When the age is
greater than delta-seconds seconds, the client SHOULD discard the
cookie. A value of zero means the cookie SHOULD be discarded
immediately.
http://www.faqs.org/rfcs/rfc2965.html
But as an alternative you can safely set the age to 5 years or 10 years later. Most probably a user would get rid of his device/PC/Mobile by this time. :)
Update:
To set the expiry time in future you can use MaxAge as following, setting it to expiry in a month:
app.use(expressSession({
secret: '',
resave: false,
saveUninitialized: false,
rolling: true,
cookie: {
secure: false,
maxAge: 30 * 24 * 60 * 60 * 1000
}
}))
This would set it to expiry

Related

Chrome stops Recaptcha v3 from sending site key to back-end?

I'm trying to add recaptcha v3 to my express app. I tried this code:
https://github.com/Leog004/RecaptchaV3-NodeJS
read this post but it did not help:
SameSite warning Chrome 77
this is what chrome says:
Because a cookie’s SameSite attribute was not set or is invalid, it defaults to SameSite=Lax, which prevents the cookie from being sent in a cross-site request. This behavior protects user data from accidentally leaking to third parties and cross-site request forgery.
Resolve this issue by updating the attributes of the cookie:
Specify SameSite=None and Secure if the cookie should be sent in cross-site requests. This enables third-party use.
Specify SameSite=Strict or SameSite=Lax if the cookie should not be sent in cross-site requests.
This is my session configuration for saving sessions to mongodb:
(I use it as app.use(session(sessionconf)) for every request in back-end)
const sessionconf = {
store: MongodbStore.create({
mongoUrl: str,
secret,
touchAfter: 24 * 60 * 60
}),
secret,
resave: false,
name: '_cloud',
saveUninitialized: false
,
cookie: {
httpOnly: true,
secure: true,
expires: Date.now() + 1000 * 60 * 60 * 1 ,
maxAge: 1000 * 60 * 60 * 1
}
}
everything looks working but when fetching the post route from the front-end, the body of post request in the back-end, shows {}

Postman receive cookies with expires: never

I use express to create cookie like this
res.cookie(user[0].email, token, {expire: new Date(Date.now()) + 1200, httpOnly: true})
It works fine when receive cookie from server as well as send cookie in the request. The only problem is that when I open cookies tab in post man it shows the expires is never.
A few things are wrong here.
You're not setting the expiry correctly: the property is named expires.
Using the + operator on Date doesn't add time, it converts to a string and concatenates a number onto the end, which is not what you want.
Check your math. JavaScript date units are typically milliseconds. Do you really want this cookie to expire 1200 milliseconds (1.2 seconds) after it's set?
This will fix the first two points:
res.cookie('abc#d.com', 'foo', { expires: new Date(Date.now() + 1200), httpOnly: true })

Express Session / Cookie maxAge property refreshes on request

Code in app.js
var cookieParser = require("cookie-parser")
var session = require("express-session")
app.use(cookieParser())
app.set('trust proxy', 1)
app.use(session(
{
"name": '***',
"secret": '***',
"cookie": {
"maxAge": null,
"expires": null,
"httpOnly": true,
"secure": true
},
"rolling": false,
"saveUninitialized": false,
"resave": false,
}))
When logging in this end point gets hit
req.session.username = email // defaults to putting something in cookie
req.session.cookie.maxAge = 1000 * 5
req.session.touch()
Test: finding the time left for cookie/session
router.get('/refresh-session', function(req, res){
if (req.session){
console.log(req.session.username)
console.log(req.session.cookie.maxAge)
}
})
My goal is to display a popup to the user in react notifying them that their session is about to expire. I will be refreshing the maxAge every time they navigate to a new page... However, before that I need to find out what the actual current maxAge is. Doing so seems to refresh the maxAge of the cookie. But this maxAge refresh isn't actually effecting the expiration time.
For example:
If maxAge is set to 5 seconds (testing purposes) then calling the method to check the maxAge will consistently be between 4800-5000 millis. However, after the 5 seconds - no matter how many times I refresh - the cookie does expire at 5 seconds (which is intended).
The thing is why id maxAge reseting?
I've looked around and found some unhelpful git pages. Here:
https://github.com/expressjs/session/issues/189#issuecomment-182631933 - doesn't work
https://github.com/expressjs/session/issues/2 - very unhelpful
Anyone run into this issue or can suggest alternatives?
The req.session.cookie.maxAge tells how much time is left in the session. It is reset at end of request to original value. This is documented in the README.md.
Your frontend can not ask the backend for how much of session is still left, because the session is touched at the request. You can set the cookie.maxAge already at the session parameters, no need to postpone until login. Your frontend should keep own timer and reset it at every request to backend.

Expiring cookies in native NodeJS

I'm trying to expire a cookie with native NodeJS, specifically for the chrome browser. However, the expiration date that I place doesn't cause the cookie to go away.
As of right now, here's my code:
var cookie = 'Expires=' + new Date();
response.setHeader('Set-Cookie', cookie);
I ended up getting cookies with the expiration date like so even after subsequent requests:
cookie: Expires=Wed Mar 22 2017 02:14:52 GMT-0400 (EDT)
You can set cookie expires and httpOnly using the below code.
res.cookie(myCookie, myValue, { expires: new Date(Date.now()+10000), httpOnly: true };
https://expressjs.com/en/api.html#res.cookie
Try This, It may work for you.
'Set-Cookie':'sesh=wakadoo; expires='+new Date(new Date().getTime()+86409000).toUTCString();
Replace sesh=wakadoo with your variable.

Destroy cookie NodeJs

I am using Cookies module for setting cookie. Here is following my code:
var options = {
maxAge: ALMOST_ONE_HOUR_MS,
domain: '.test.com',
expires: new Date(Date.now() + ALMOST_ONE_HOUR_MS)
};
var value = userInfo.token;
cookies.set("testtoken", value, options);
But in documentation I haven't found how to destroy this cookie.
Any suggestion would be appreciated.
For webapp you can just set cookie in response as :
res.cookie("key", value);
and to delete cookie :
Ref: https://expressjs.com/en/api.html#res.clearCookie
res.clearCookie("key");
and don't forget to:
res.end()
to avoid the web request hanging.
There is no way to delete a cookie according to the HTTP specification. To effectively "delete" a cookie, you set the expiration date to some date in the past. Essentially, this would result in the following for you (according to the cookies module documentation):
cookies.set('testtoken', {maxAge: 0});
Or according to the HTTP specification:
cookies.set('testtoken', {expires: Date.now()});
Both of which should work. You can replace Date.now() with new Date(0) for a really old date.
While one other answer is correct, deleting a cookie from an express.js webapp is done by invocing the following method:
res.clearCookie("key");
But there's a caveat!
Your cookie options (except expires) need to be the same as when you set it. Otherwise browsers will NOT remove the cookie. So use the same domain, security setting etc. (reference: https://expressjs.com/en/4x/api.html#res.clearCookie)
I'm using this with cookie-parser module:
router.get('/logout', function(req, res){
cookie = req.cookies;
for (var prop in cookie) {
if (!cookie.hasOwnProperty(prop)) {
continue;
}
res.cookie(prop, '', {expires: new Date(0)});
}
res.redirect('/');
});
I was going through the same problem a few days ago. After discussing it with a friend, I think this is the best solution.
res.setHeader('set-cookie', 'mycookie=; max-age=0');
Advantages:
only use node
simple to understand
credits: #andy
To delete any http cookie if we just try to clear it from response [using res.clearCookie("key")], it is definitely not going to work. In reality, to delete http cookie, domain and path are very important.
Domain and path define the scope of the cookie. In face, they essentially tell the browser what website the cookie belongs to.
Sending the same cookie value with ; expires appended is also a bad idea since you want the content to be destroyed, but that is not going to happen.
The best idea would be invalidating the cookie by setting the value to empty and include an expires field as well like below:
res.cookie("key","empty the key content", {expires:old date, domain:'.example.com', path:'/'});
res.cookie("token", "", { expires: new Date(0),domain:'.test.com', path: '/' });
Hope this helps!!!
I am using cookie-parser as well, and upper answers lead me to the solution. In my case I needed to add overwrite: true as well, otherwise new cookie key was added.
So my final solution looks like:
res.cookie('cookieName', '', {
domain: 'https://my.domain.com',
maxAge: 0,
overwrite: true,
});
When using in production with SSL, you need to specify the domain. This domain must correspond to the one, which is used to store the cookie!
For example:
res.clearCookie('sid', {domain: ".somedomain"})
create cookie with expires time
res.cookie("keyname", data, {
expires: new Date(Date.now() + 1000 * 60 * 15),
})
Remove cookie
res.clearCookie("key name here");
I have tried all the solutions, and none worked until I found this one.
I set up my cookie like this:
res.writeHead(200, {
"Set-Cookie": `token=${accessToken}; HttpOnly; path=/`,
"Access-Control-Allow-Credentials": "true",
});
res.end();
Then destroyed it like this:
res.writeHead(200, {
"Set-Cookie": `token=; HttpOnly; path=/; max-age=0`,
});
res.end();
Another way to destroying cookies from the server. Just set negative integer as a maxAge. One more thing that keep in mind, don't forget to set a path when will set or destroy cookie.
The Best way to doing this
before you set the like token you should remove that first
like that
res.clearCookie('token');
res.cookie('token',token, { maxAge: 900000, httpOnly: true });

Resources