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 {}
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
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 })
Giving some code that I have tried so far.
Request-origin - "abc.com", Request-url - "login.abc.com/login" (Post method)
function setCookie(req, res)
{
//Some code goes here.
//Code to set cookie
res.cookie('test',"some value"); //This should set cookie for login.abc.com, which never happened
}
Also tried to set for domain
function setCookie(req, res)
{
//Some code goes here.
//Code to set cookie
res.cookie('test',"some value",{domain:'.abc.com'},{'path' : '/'});//This should set cookie for .abc.com
}
Following code is working as expected
Request-origin - "abc.com", Request-url - "abc.com/login" (Post method)
function setCookie(req, res)
{
//Some code goes here.
//Code to set cookie
res.cookie('test',"some value",{domain:'.abc.com'},{'path' : '/'});//This set the cookie for .abc.com successfully
}
Can someone help me to understand why it is not setting cookie in the first case but it is setting cookie in the second case?
NOTE I am trying this in my local.
So finally I got the solution to my issue and able to achieve what I want. Writing this answer, so that some one else can get benifit in the future.
Changes in client side:-
$.ajax({type: "post",
data: {},
timeout: 30000,
dataType:"json",
xhrFields : {withCredentials : true} //Need to add this along with the request.
})
Now server side changes:-
var cors = require('cors');
app.post('/testRoute',
cors({credentials:true,
origin:'http://example.com'}), //Origin should be the url of the page, from where we are sending request.
function(req, res){
res.cookie('test',"some value",{'path' : '/'})
})
Refer cors-doc to know more about how to use cors in server side.
NOTE:- Can not use Access-Control-Allow-Origin value as * if xhrFields : {withCredentials : true} we are specifying in the ajax request.
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 });