【问题标题】:Cookie is not sent with CORS web requestCookie 未随 CORS Web 请求一起发送
【发布时间】:2021-08-11 21:17:08
【问题描述】:

我正在尝试设置一个带有过期日期的 cookie:

response.Cookies.Append("theKey", value, new CookieOptions() { Expires = DateTime.Now.AddMonths(12) });

cookie 存储在浏览器中,但不会在后续的跨站点 Web 请求中发送。

当我尝试设置不带 Expires 日期的 cookie 时,会发送 cookie,但它仅在浏览器打开时存储在浏览器中(会话 cookie)。

这是一个跨站点请求。调用该函数的javascript代码是:

var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url, true);
xmlHttp.withCredentials = true;
xmlHttp.onreadystatechange = function () {
    if (this.readyState == 4 && this.status == 200) {
        //console.log(this.responseText);
    }
};
xmlHttp.send(null);

有没有办法在跨站点请求中发送包含Expires 日期的cookie?

客户端 Web 应用和函数应用(尝试设置 cookie)都使用 https。

这是设置 cookie 过期日期的 HTTP 响应:

【问题讨论】:

  • @MartinStaufcik 如果你使用 Postman,你会得到同样的行为吗? Postman 不会检查跨域,因此您可以尝试保持代码原样并删除 CORS,并检查 cookie 是否在响应中正确传递。
  • 除了弄清楚为什么会这样,如果你保存一年,那为什么不直接使用 localStorage
  • @mplungjan 我不能使用localStorage,因为我需要能够在后续的网络请求中发送cookie,它会识别用户
  • 但是你至少可以在没有过期的情况下发送它
  • @Manuel 我尝试在 Chrome 中查看其他域的 cookie,cookie 保存在浏览器中,所以问题是 cookie 没有在后续请求中发送。我可能会通过在 javascript 中创建第一个域 cookie 并将其作为 ajax 调用中的参数发送来解决它。

标签: javascript .net-core cors asp.net-core-2.1


【解决方案1】:

解决办法是设置cookie的SameSite属性。这允许将 cookie 与来自 JavaScript 代码的跨站点请求一起发送。

SameSite 属性 (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) 的可能值:

  • 严格 - 不为跨站请求发送 cookie
  • lax(默认值)- 仅当用户点击常规链接(例如点击)时,才会为跨站点请求发送 cookie
  • 无(以前的默认值)- 为跨站点请求发送 cookie

在 .NET Core 中,cookie 需要使用SameSite 属性显式设置,因为默认为lax

response.Cookies.Append("theCookie", value, new CookieOptions() 
{ 
    Expires = DateTime.Now.AddMonths(12), 
    SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None 
});

【讨论】:

  • 如果我按照您的描述将 samesite 设置为 none,它会起作用。是不是比“同一个站点”更不安全?
  • 是的,默认情况下它的安全性较低。例如,如果它是一个会话 ID,其他网站可以发送请求并自动进行身份验证。但是,浏览器中还实现了其他机制来防止这种情况发生,例如Access-Control-Allow-Origin
【解决方案2】:

您的服务器需要包含以下 CORS 响应标头:

 Access-Control-Allow-Credentials: true

除了您已经发送的 Access-Control-Allow-Origin 标头之外。

没有 ACAC 标头,浏览器将不会处理来自源的任何 Set-Cookieresponse 标头。我怀疑 cookie 是由不同响应中的 Set-Cookie 响应标头设置的。

【讨论】:

  • 哪个服务器?如果浏览器访问站点 A 并返回 cookie,则用户(在同一页面上)访问站点 B - 站点 B 接收到 cookie 需要发生什么?请注意,两个站点都在同一个域中,但显然“同一个站点”并不能说明这一点。
  • 如果两个站点在同一个域中(即使是同一个基域,例如如果 A 是 foo.example.com 而 B 是 bar.example.com),如果 foo.example.com 创建了一个cookie(通过 Set-Cookie 响应标头),其 Domain 属性为“.example.com”,那么理论上,它将被传递给 bar.example.com。但是如果对 foo.example.com 的请求是一个没有返回 ACAC: true 的 CORS 请求,那么浏览器将“转储” Set-Cookie 标头,并且永远不会创建它...
  • 好的,我很高兴这应该工作。我已经设置了与您的示例相同的域中的站点。我可以看到 cookie 与站点 A 来回传递,但即使有此标头和原始设置,它也永远不会到达站点 B。 cookie 设置为 samesite,但域完全相同(不同的端口,如果重要的话)。我会稍微研究一下,如果我不能得到它,请提出一个问题。
猜你喜欢
  • 2019-01-17
  • 2012-11-28
  • 2021-05-29
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
相关资源
最近更新 更多