12

I'm trying to set a cookie in my application.

Here's the code that sets the cookie:

public HttpResponseMessage LogIn(UserLoginVM user) { // Do login stuff var cookie = new CookieHeaderValue("STUPID-COOKIE", "12345"); cookie.Domain = Request.RequestUri.Host; cookie.Path = "/"; cookie.HttpOnly = true; // Get user's profile HttpResponseMessage res = Request.CreateResponse<UserProfileVM>(HttpStatusCode.OK, profile); res.Headers.AddCookies(new CookieHeaderValue[] { cookie }); return res; } 

The response from the server is the following:

HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Type: application/json; charset=utf-8 Expires: -1 Server: Microsoft-IIS/8.0 Set-Cookie: STUPID-COOKIE=12345; domain=localhost; path=/; httponly Access-Control-Allow-Origin: * X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?QzpcUFJPSkVDVFNcU2Ftc2tpcC5TZXJ2aWNlV2ViTmV3XFNhbXNraXAuQXV0aEFQSVxTYW1za2lwLkF1dGhBUElcbG9naW4=?= X-Powered-By: ASP.NET Date: Wed, 18 Feb 2015 11:58:07 GMT Content-Length: 8019 

Notice the following header:

Set-Cookie: STUPID-COOKIE=12345; domain=localhost; path=/; httponly 

However, when I go under "Cookies" in "Resources" tab in Chrome, nothing is set. Also when I send a request to the server no cookie is in the headers.

Here's the code that reads the cookie:

CookieHeaderValue cookie = Request.Headers.GetCookies("STUPID-COOKIE").FirstOrDefault(); 

cookie variable is always null.

My application is running on http://localhost:53998 and the authentication service is running on http://localhost:60858

My Chrome version is 40.0.2214.111.

Here's a GIF demonstrating the problem: https://i.sstatic.net/86Xug.gif

Edit: This seems to be non-specific to Chrome. This doesn't work on FireFox (v35) either. GIF: https://i.sstatic.net/yFuzd.gif

3 Answers 3

3

I ran into this issue today and Gaui's answer was quite useful to me, bearing in mind ideally you do not want to open up your server to CORS requests from any site. I'm in my dev environment and my server and client are on different origins since they are on different ports on localhost. Also I'm using .net core 3.0

My issue was caused by my server not sending cookies to my client side as my CORS settings were blocking the sending of cookie to my domain this was evident by the server not using the header Access-Control-Allow-Credentials: true. To resolve this I configured my server in Startup.cs to allow requests from my client side to allow credentials (A credential is a cookie's authorization headers or TLS client certificates).

 var allowedOrigins = new[] {"localhost:3000"}; // Ideally comes from appsettings app.UseCors(builder => builder.WithOrigins(allowedOrigins).AllowCredentials().AllowAnyMethod().AllowAnyHeader().Build()); 

For the cookie options; I found that the you do not have to set Domain if you do not want to, Secure works even when the site is not using https.

Google chrome now supports cookies on localhost, I believe it didn't used to as a lot of older SO posts have users who faced that issue.

On the client side, you need to configure it to accept cookies as well, as in Gaui's answer above. I was using fetch, and so had to add the option:

credentials: 'include' 

Which tells fetch to retrieve cookies across domains. See the docs here

Sign up to request clarification or add additional context in comments.

2 Comments

Unfortunately, does not work in my case :( I checked whatever I could: having valid certificate on localhost now, followed yours and other advices... COOKIE IS NOT SAVED. Probably I'm missing something. I'm navigating Angular site, which in addition to IdentityServer and HttpApiHost (where I try to set cookie) are hosted on localhost and CORS is setup...
the last point works for me im using axios "axios.defaults.withCredentials = true" but i unfortunalely doesnt work with a httponly true
1

I highly suspect that localhost is not a valid domain name so Chrome rejects it. If you simply remove 'domain=localhost' from the Set-Cookie then it will work and Chrome will assign the domain to localhost for you.

I would personally create a local domain name like "test.dev" and add it to your Windows hosts file, 127.0.0.1 test.dev

1 Comment

This was another problem, removing domain name didn't work. See answer below.
-2

I finally managed to solve this.

In the response from the API I had to add Access-Control-Allow-Credentials: true headers, or by adding the following in the WebApiConfig class:

public static void Register(HttpConfiguration config) { var cors = new EnableCorsAttribute("*", "*", "*"); cors.SupportsCredentials = true; config.EnableCors(cors); } 

Then I had to enable it on the client-side, by setting the withCredentials property in the XMLHTTPRequest object to true. In AngularJS app config function you can do the following:

$httpProvider.defaults.withCredentials = true; 

Also, for Chrome, I had to omit the Domain (or set it as null).

Hope this helps others struggling with this.

1 Comment

EnableCorsAttribute("", "", "*") is extremely dangerous and should never be done. You throw away almost all same-origin policy protections and open users of your app to a broad variety of cross-site attacks including those involving browser header forgery. You should be precise in what domains, headers, and methods you allow.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.