首页 > 解决方案 > Cookie 忽略 DotNet Core 中的 CORS 设置

问题描述

我的目标是发出一个 GET 请求,包括一个 cookie,从将托管在多个域上的 javascript 到一个公共域上的 API。如果 cookie 丢失,我会创建一个并将其返回以在后续请求中使用。

最初我遇到了浏览器拒绝允许 jQuery 访问与页面域不同的域的问题,我知道这与 CSRF 保护有关。

我尝试了数十种不同的方法来使用我的 DotNet Core 2.1 API 项目设置 CORS,例如在这个问题中描述的:如何在 ASP.NET Core 中启用 CORS,以及许多类似这样的博客:https://weblog.west- wind.com/posts/2016/Sep/26/ASPNET-Core-and-CORS-Gotchas

虽然我能够摆脱 CSRF 问题,但 cookie 从未在请求​​中传递,因此每次服务器创建一个新的并将其发送回时,浏览器要么不保留它,要么不随后续请求发送它到服务器。

然后我发现如果我将这SameSite = SameSiteMode.None一行添加到我的 cookie 创建中,它会起作用:

[HttpGet("[action]")]
public async Task<IActionResult> Track()
{
    const string cookieName = "TrackingCookie";
    string uniqueId = Request.Cookies[cookieName];

    if (string.IsNullOrWhiteSpace(uniqueId))
    {
        uniqueId = "123"; // debug - this would be generated

        Response.Cookies.Append(cookieName, uniqueId, new CookieOptions
        {
            SameSite = SameSiteMode.None,
            Expires = DateTimeOffset.UtcNow.AddSeconds(30) // debug - short duration for testing only
        });

        logger.LogWarning($"Cookie missing, so created it with unique id '{uniqueId}'.");
        return Created(Url.Action(), $"Created unique id '{uniqueId}'.");
    }

    logger.LogWarning($"Cookie found, unique id '{uniqueId}' present.");
}

但是,我还发现,如果我从 Startup.cs 文件中删除所有与 CORS 相关的声明,它仍然有效。如果我完全删除它仍然有效:

services.AddCors(options => options.AddPolicy("MyPolicy", builder =>
{
    builder.WithOrigins("http://markscoolsite.com:5000")
           .AllowAnyMethod()
           .AllowAnyHeader();
}));

和:

app.UseCors("MyPolicy");

此外,无论我将它放在哪个域中,cookie 都有效,因此它显然不承认该指​​令WithOrigins(...)

作为参考,这是我的 javascript 代码:

$(function () {
    $.ajaxSetup({ xhrFields: { withCredentials: true } });

    $.get('http://localhost:5000/api/tracking/track')
        .done(console.log);
});
  1. 为什么此 cookie 适用于任何来源,而不需要在链接问题和无数其他问题中描述的 Startup.cs 中的任何 CORS 添加?我是否完全误解了 MVC6 中的 CORS 是什么?
  2. 如何将我的 cookie 限制为仅在我指定的站点上工作?我担心我让它工作的方式可能不是很安全。

标签: asp.net-corecookiescross-domaincsrf

解决方案


好的,我想通了。

CORS 基本上与服务器将接收什么无关,而是浏览器将接受什么作为响应。如果没有以下代码,浏览器会因为反 CSRF 保护而拒绝服务器的响应:

app.UseCors(configurePolicy =>
{
    configurePolicy.WithOrigins("http://markscoolsite.com:5000")
                   .AllowCredentials();
});

因此,如果我希望浏览器接收任何内容,则需要此代码。我只关注服务器对 cookie 的接收。


推荐阅读