I am trying to set a cookie with Expires date:
response.Cookies.Append("theKey", value, new CookieOptions() { Expires = DateTime.Now.AddMonths(12) });
the cookie is stored in the browser but is not sent in a subsequent cross-site web request.
When I try set the cookie without the Expires
date, the cookie is sent, but it is stored in the browser only while the browser is open (session cookie).
It is a cross-site request. The javascript code that calls the function is:
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url, true);
xmlHttp.withCredentials = true;
xmlHttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
xmlHttp.send(null);
Is there a way to send a cookie containing Expires
date in a cross-site request?
Both the client web app and the function app (that attempts to set the cookie) use https.
This is the HTTP response setting the cookie with expiration date:
I am trying to set a cookie with Expires date:
response.Cookies.Append("theKey", value, new CookieOptions() { Expires = DateTime.Now.AddMonths(12) });
the cookie is stored in the browser but is not sent in a subsequent cross-site web request.
When I try set the cookie without the Expires
date, the cookie is sent, but it is stored in the browser only while the browser is open (session cookie).
It is a cross-site request. The javascript code that calls the function is:
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url, true);
xmlHttp.withCredentials = true;
xmlHttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
xmlHttp.send(null);
Is there a way to send a cookie containing Expires
date in a cross-site request?
Both the client web app and the function app (that attempts to set the cookie) use https.
This is the HTTP response setting the cookie with expiration date:
Share Improve this question edited Mar 16, 2019 at 8:20 Martin Staufcik asked Mar 1, 2019 at 10:29 Martin StaufcikMartin Staufcik 9,4827 gold badges56 silver badges75 bronze badges 5- @MartinStaufcik if you use Postman, do you get the same behaviour? Postman does not check for cross origin, so you can try to keep your code as it is and remove CORS, and check if the cookie is passed correcly in the response. – Norcino Commented Mar 1, 2019 at 10:50
- Apart from figuring out why this happens, If you save this for a year, then why not just use localStorage – mplungjan Commented Mar 1, 2019 at 10:53
- @mplungjan I cannot use localStorage, because I need to be able to send the cookie in a subsequent web request, it identifies the user – Martin Staufcik Commented Mar 1, 2019 at 11:06
- But then you can send it without expiry at least – mplungjan Commented Mar 1, 2019 at 11:20
- @Manuel I tried to look into the cookies of the other domain in Chrome, the cookie is saved in the browser, so the problem is the cookie is not sent in subsequent request. I will probably solve it by creating a first domain cookie in javascript and sending it as a parameter in the ajax call. – Martin Staufcik Commented Mar 1, 2019 at 14:32
2 Answers
Reset to default 9The solution is to set the cookie's SameSite
attribute. This allows sending the cookie along with cross-site requests from JavaScript code.
Possible values of SameSite
attribute (https://developer.mozilla/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite):
- strict - the cookie is not sent for cross-site requests
- lax (the default) - the cookie is sent for cross-site requests only when the user follows a regular link (e.g. clicking)
- none (previous default) - the cookie is sent for cross-site requests
In .NET Core, the cookie needs to be explicitly set with the SameSite
attribute, since the default is lax
:
response.Cookies.Append("theCookie", value, new CookieOptions()
{
Expires = DateTime.Now.AddMonths(12),
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None
});
You server needs to include the following CORS response header:
Access-Control-Allow-Credentials: true
in addition to the Access-Control-Allow-Origin
header you're already sending.
Without the ACAC header, the browser will not process any Set-Cookie
response headers from the origin. I suspect the cookie is being set by a Set-Cookie response header in a different response.