Reputation: 4125
I have a problem where cookies set in the website using javascript are not being passed to controllers in the Request. Any cookies set in C# are present.
In my Startup.cs I have set the following:
ConfigureServices:
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;// must be false otherwise only essential cookies will be allowed
options.MinimumSameSitePolicy = SameSiteMode.None;
});
Configure:
app.UseCookiePolicy(new CookiePolicyOptions
{
HttpOnly = HttpOnlyPolicy.None
});
when inspecting the cookies in the browser the one I want - "ClientTimeZone" is present as can be seen in this image:
but in the controller when looking at the Request that cookie is not present:
The JavaScript code I use to store cookies are as follows:
setCookie: function (name, value, days)
{
var expires = "";
if (days)
{
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + ";";
},
I have also tried adding path=/
but no luck.
Any suggestions as to why the cookie does not persist to the server?
Thanks,
Upvotes: 1
Views: 1511
Reputation: 345
This is due to spaces in your cookie value (and in my case, Json). .NET Core is using RFC-6265.
Allowed characters are alphanumerics plus ~!@#$%^&*()-_+[]{}|
. Space, comma, semi-colon, backslash, and quotes are not allowed.
The simplest fix is to use Uri encoding/decoding.
Javascript to set cookie value:
document.cookie = 'ClientTimeZone=' + encodeURIComponent("New Zealand Time") + ';path=/';
C# to read it:
var timeZone = System.Net.WebUtility.UrlDecode(Request.Cookies["ClientTimeZone"]);
The source of the issue is when parsing header values into cookies:
Microsoft.Net.Http.Headers.HttpHeaderParser
{
protected virtual bool TryParseValues(IList<string> values, bool strict, out IList<T> parsedValues)
}
Eventually hits the following method, which exits as soon as it hits a disallowed character:
Microsoft.Net.Http.Headers.CookieHeaderValue
{
internal static StringSegment GetCookieValue(StringSegment input, ref int offset)
}
Essentially, even though the cookie is sent in the request header, any cookie that doesn't parse correctly is silently ignored and never included in the IRequestCookieCollection Request.Cookies.
Upvotes: 3