Browser not sending cookies cross-origin cross domain with CORS enabled

Viewed 2305

I have a .net core webapi project set up to accept cross origin requests like so

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors();
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}


public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    app.UseCors(opts => opts
        .WithOrigins("https://fiddle.jshell.net")
        .AllowCredentials()
        .AllowAnyMethod()
        .AllowAnyHeader());

    app.UseHttpsRedirection();
    app.UseMvc();
}

This has a values controller with a GET method like so

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return Ok("cookies: " + string.Join(", ", HttpContext.Request.Cookies.Select(x => x.Key)));
    }
}

Now I am trying to send a fetch request from the browser like so

fetch('https://api.domain.com/api/values', { 
    headers: 
    { 
      'Content-Type': 'application/json' 
    }, 
    credentials: 'include', 
    mode: 'cors'
})
.then(function(resp){ 
    resp.text().then(function(data) { 
        console.log(data); 
  }) 
})
.catch(function(err){ 
    console.log(err) 
});

But this doesn't send the cookies from the page to the api. What am I missing here? I have tried all the solutions I could find about this including turning off third party cookies

Update

So, I still don't have an answer to why this doesn't work or any authoritative sources saying you can't send cookies cross-domain (or even one that says cross-origin != cross-domain).

What we found is that even cookies from sub-a.domian.com would not be sent to sub-b.domain.com. The way we 'solved' this is to create a cookie that is permanently bound to domain.com because those cookies are sent to sub-a.domain.com and sub-b.domain.com.

2 Answers

The only thing CORS does is let the browser use the response from a cross-origin request, it will not make cookies cross-domain (see the specification for more details on the conditions for attaching a cookie to a request, it does not mention CORS at all).

If cookies could be sent along cross-origin request, that would be a major security flaw, since it would allow foreign domains to get sensitive information like user session tokens from your own domain. An evil developer could create an API providing a useful service, and then retrieve tons of session tokens from websites using the API (originating websites could be easily found through the Referer header).

The behavior you observed with localhost and different ports is normal since ports are not taken in account for cookies, which is "for historical reasons" (for reference: Are HTTP cookies port specific?)

So the options left for you are:

  • Set the cookie domain to a parent domain
  • Considering your server can work with headers instead of cookies, do not use cookies at all (use localStorage with javascript, and HTTP headers, for example)
  • Considering you have hands on the infrastructure, use a single domain for both UI and API, and do some URL rewriting on server side (e.g: incoming requests starting with /api/... are rewritten with the local API URL, others are rewritten with the local UI URL)

Browser not sending cookies cross-origin cross domain with CORS enabled.

Every cook has domain associated with it so you can use *.abc.com and use it on abc.com and all subdomains of abc.com So make sure your cookies are *.abc.com options.Cookie.Domain = ".contoso.com";

see my link sharecookies like this

services.AddCors(options =>
        {
            options.AddPolicy(MyAllowSpecificOrigins,
            builder =>
            {
                builder.WithOrigins("http://example.com","*.example.com"
                                    "http://www.contoso.com");
            });
        });
Related