浏览器未在启用了CORS的情况下跨域发送Cookie跨域

时间:2019-06-24 06:54:37

标签: javascript c# .net asp.net-core cors

我有一个.net核心webapi项目设置为接受跨源请求,像这样

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();
}

它具有一个带有GET方法的值控制器

[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)));
    }
}

现在我正试图从浏览器发送获取请求

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) 
});

但这不会将cookie从页面发送到api。我在这里想念什么?我已经尝试过所有可以找到的解决方案,包括关闭第三方Cookie

更新 我应该提到,正在发送来自同一域的Cookie,但不是从子域发送的。例如,如果后端URL是api.domain.com,然后UI处于ui.domain.com,则属于domain.com的任何cookie都会被发送,而属于ui.domain.com的cookie不会被发送。

2 个答案:

答案 0 :(得分:0)

CORS唯一要做的就是让浏览器使用跨域请求的响应,它不会使cookie成为跨域的(有关将cookie附加到网址的条件的更多详细信息,请参见specification要求,它根本没有提到CORS)。

如果可以按照跨域请求发送cookie,那将是一个主要的安全漏洞,因为它会允许外部域从您自己的域中获取敏感信息,例如用户会话令牌。邪恶的开发人员可以创建提供有用服务的API,然后使用该API从网站中检索大量会话令牌(可以通过Referer标头轻松找到原始网站)。

您在localhost和不同端口上观察到的行为是正常的,因为cookie并未考虑端口,这是“出于历史原因”(供参考:Are HTTP cookies port specific?

所以剩下的选项是:

  • 将Cookie domain设置为父域
  • 考虑到您的服务器可以使用标头而不是cookie,请不要使用cookie(例如,将localStorage与javascript和HTTP标头一起使用)
  • 考虑您拥有基础结构,将UI和API都使用一个域,并在服务器端进行一些URL重写(例如:以/api/...开头的传入请求将用本地API URL重写,其他用本地UI URL重写)

答案 1 :(得分:-2)

浏览器未在启用了CORS的情况下跨域发送Cookie。

每个厨师都有与之关联的域,因此您可以使用* .abc.com并在abc.com和abc.com的所有子域上使用 因此,请确保您的Cookie是* .abc.com options.Cookie.Domain =“ .contoso.com”;

查看我的链接 sharecookies like this

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