首页 > 解决方案 > 发出 AJAX 跨源请求时,如何防止“与没有 SameSite 属性的跨站点资源集关联的 cookie”警告?

问题描述

所以,我有两个站点 http://localhost/ 和 http://3rdPartyLocallyHostedAPI/ (不是真实姓名) - 都是本地 Intranet 站点,并且由于3rdPartyLocallyHostedAPI其同名的性质,localhost必须向它发出 CORS 请求.

这些请求工作正常,数据返回或可以3rdPartyLocallyHostedAPI按预期发布,但是显示此警告:

在 http://3rdPartyLocallyHostedAPI/ 处设置了与跨站点资源关联的 cookie,但未设置该SameSite属性。未来版本的 Chrome 将仅提供带有跨站点请求的 cookie,前提是它们使用SameSite=None和设置Secure。您可以在应用程序>存储>Cookies 下的开发人员工具中查看 cookie,并在https://www.chromestatus.com/feature/5088147346030592https://www.chromestatus.com/feature/5633521622188032中查看更多详细信息。

现在,我查看了多个答案,例如this onethis onethis one,它们声明需要在服务器上设置 SameSite 属性,这没有任何意义,因为它所涉及的两个 cookie (ss -pid 和 ss-id) 在请求中设置,而不是在响应中返回?这让我很困惑,因为我不知道如何或在哪里进行更改以确保将这些 cookie 上的 SameSite 策略设置为nonesecure

我认为执行 AJAX 请求的 jQuery 是有问题的:

// trimType and queryValue are determined elsewhere by some jQuery selections, their values are not important to the question being asked.
$.ajax({
    url: 'http://3rdPartyLocallyHostedAPI?q=' + trimType + '?q=' + queryValue + '&resultsOnly=true',
    data: {
        properties: (trimType === 'Record') ? 'Title,Number,RecordRecordType' : 'NameString'
    },
    xhrFields: {
        withCredentials: true
    },
    dataType: 'json'
}).done(function (data) {
    if (data.Results.length > 0) {
        $resultsPane.html('');
        for (var i = 0; i < data.Results.length; i++) {
            // Not relevant to the question being asked so removed, only some jQuery in here to display results on page.
        }
    } else {
        $resultsPane.html('<p class="py-1 pl-1 list-group-item text-muted">No Results found.</p>');
    }
}).fail(function () {
    $resultsPane.html('<p class="py-1 pl-1 list-group-item text-muted">No Results found.</p>');
});

如果它没有withCredentials = true设置属性,因此针对 API 进行匿名身份验证(仅提供有限的访问权限,因此需要传递 Windows 凭据),SameSite则不会出现警告。这是请求标头:

GET /CMServiceAPIAuth/Location?q=%22SDC%20*%22&resultsOnly=true&properties=NameString HTTP/1.1
Host: serverName
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36
Origin: http://localhost:64505
Referer: http://localhost:64505/Home/DisplayRecord
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cookie: ss-pid=OQtDrnmok62FvLlZPnZV; ss-id=cIaIcS3j0jmoouAaHHGT

chrome 遇到问题的两个 cookie 是ss-pidss-id,响应标头没有传回 cookie:

HTTP/1.1 200 OK
Cache-Control: private,no-cache
Content-Type: application/json; charset=utf-8
Vary: Accept
Server: Microsoft-IIS/8.5
X-Content-Type-Options: nosniff
X-Powered-By: ServiceStack/4.512 NET45 Win32NT/.NET
X-AspNet-Version: 4.0.30319
Access-Control-Allow-Origin: http://localhost:64505
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST,GET,OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Mon, 27 Jul 2020 07:02:06 GMT
Content-Length: 1597

那么,考虑到所有这些,有人可以解释我哪里出错了吗?我是否需要对 jQuery AJAX 进行更改以防止出现此警告(并因此在警告提醒我发生更改时防止将来出现问题) - 或者,我是否真的需要在服务器上设置一个额外的标头,我'我想知道是否在飞行前 OPTIONS 请求中它是否试图找出请求的 SameSite 设置或类似的东西?

通过 IIS 模块,我确实可以向服务器发送的响应添加额外的标头,所以如果这是需要的,我可以做到 - 我只是不太明白警告是在哪一端引起的并希望人们能提供任何解释。

标签: javascriptasp.netcookiescross-domainsamesite

解决方案


好吧,我想我已经做了足够的研究来弄清楚我面临的问题,所以我会回答我自己的问题。

因此,真正帮助我真正理解 SameSite 是什么的一页是这一页,所以对于其他遇到 SameSite 问题的人,请阅读以了解其背后的原因及其工作原理。

做了一些阅读并看到另一个帖子的答案帮助我把这些点联系起来。我将正在开发的网站部署到实际的 Web 服务器上,发现以下是响应标头:

HTTP/1.1 200 OK
Cache-Control: private,no-cache
Content-Type: application/json; charset=utf-8
Vary: Accept
Server: Microsoft-IIS/10.0
X-Content-Type-Options: nosniff
X-Powered-By: ServiceStack/4.512 NET45 Win32NT/.NET
X-AspNet-Version: 4.0.30319
Set-Cookie: ss-pid=0QyVIKf4edkAKd2h4be5; expires=Fri, 27-Jul-2040 09:58:39 GMT; path=/; HttpOnly
Set-Cookie: ss-id=fmM1WQsDxXGfR8q9GL6e; path=/; HttpOnly
Access-Control-Allow-Origin: http://server
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST,GET,OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Persistent-Auth: true
WWW-Authenticate: Negotiate oYG2MIGzoAMKAQChCwYJKoZIgvcSAQICooGeBIGbYIGYBgkqhkiG9xIBAgICAG+BiDCBhaADAgEFoQMCAQ+ieTB3oAMCARKicARusah2q1K2ACHwoq1n6DCNq5rx/HFdbK5sU9EohnxrRSpzmelskTTa9xmW8wgeUdwRNQCqMsD/dZ/pUjhdl2CVWjmFZZAfnKl6JEker+s79E9uFXThZZKnqfpqEgSvvqSYpp1KMkaYBYd1uf5mRyE=
Date: Mon, 27 Jul 2020 09:58:40 GMT
Content-Length: 1597

Set-Cookie服务器发出两个标头来存储ss-id和的值ss-pid。这些 cookie显然代表永久会话 ID 和会话 ID,并由 ASP.NET 发布用于跟踪会话。浏览器不接受和设置这两个 cookie,因为它们缺少SameSite=none设置和Secure设置 - 这是我在上面提到的帖子中提到的两个 cookie。

所以要解决这个问题,首先我需要切换到对 API 使用 https(可能还有网站本身)——我已经这样做了,并以某种方式弄清楚如何让第 3 方 API 在它的会话中设置 SameSite 属性相关的 cookie。

因此,对于希望完全控制您的 API 等的其他人,您应该能够在创建/发送响应中的 cookie 时设置这些属性,因此可以通过设置SameSite=None和将 cookie 从站点发送到其他域Secure


推荐阅读