最新 Chrome 85 更新后的 CORS 问题

Posted

技术标签:

【中文标题】最新 Chrome 85 更新后的 CORS 问题【英文标题】:CORS Issue after latest Chrome 85 Update 【发布时间】:2020-12-19 07:13:22 【问题描述】:

我是一个非常新的用户,所以如果我违反任何规则,请提前道歉。这是我面临的问题,需要建议。

我有一个 Chrome 扩展程序,它与 Gmail 一起使用,并通过 Rails 应用程序的 Phusion Passenger 服务器使用我在 nginx 上运行的 Web 服务器的 API。

我的 Nginx 版本是 nginx 版本:nginx/1.15.8,Phusion Passenger 版本是 Phusion Passenger Enterprise 6.0.1

我在 nginx 中的 CORS 设置如下:

####### CORS Management ##########

add_header 'Access-Control-Allow-Origin' 'https://mail.google.com,https://*.gmail.com';

add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE, HEAD';

add_header Referrer-Policy "no-referrer";

add_header Pragma "no-cache";

##################################

这在 Chrome 84 之前一直有效,但是,随着 Chrome 85 的最新更新,它开始抛出 CORS 错误,如下所示:

########## Chrome 85 中开始出现错误############

CORS 政策已阻止从源“https://mail.google.com”获取“https://my-site.com/”的访问权限:没有“Access-Control-Allow-Origin”标头存在于请求的资源上。

##########################################

在此之后,我根据来自各种来源和博客的建议/参考将 CORS 设置更新为全开放,现在更新后的 CORS 设置如下所示:

Nginx 中更新的 CORS 设置

 location / 

     if ($request_method = 'OPTIONS') 

        add_header 'Access-Control-Allow-Origin' $http_origin always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #

        add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type' always;
        
        #
        # Tell client that this pre-flight info is valid for 20 days
        #

        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8' always;
        add_header 'Content-Length' 0 always;

        return 204;
     

     if ($request_method = 'POST') 

        add_header 'Access-Control-Allow-Origin' $http_origin always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type' always;

     

     if ($request_method = 'GET') 

        add_header 'Access-Control-Allow-Origin' $http_origin always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type' always;

     


###########################################

在 Nginx 中更新此设置后,CORS 错误消失了,但现在我在扩展程序调用 API 时从服务器收到 401 Unauthorized 错误。

我尝试调整所有方法,但无法修复它。有什么我遗漏或做不同的事情吗?

请帮忙!

【问题讨论】:

【参考方案1】:

这不就是这个规范改变的效果吗?

Chrome 扩展内容脚本中跨域请求的更改 https://www.chromium.org/Home/chromium-security/extension-content-script-fetches

【讨论】:

【参考方案2】:

我遇到了同样的问题。我的解决方案是(如上面链接中所述)将 Http-Requests 移动到后台内容脚本中。您需要向后台脚本发送消息并从那里执行请求。

收到响应后,您需要向内容脚本发送一条消息,您可以在其中处理响应数据。

ContentPage                  BackgorundPage
          -- RequestData -->
                              Initialize the request and return to the content script
.... some time later....
                              Callback of HttpRequest is finished
         <-- handleResponse--  (In callback handler)

内容脚本:

var msg = new Object();
msg.message = "loadOrders";
chrome.runtime.sendMessage(msg);

背景脚本:

chrome.runtime.onMessage.addListener(
function (msg, sender, sendResponse) 
    if( msgName=="loadOrders") 
        doXHRRequest( function(responseData) 
           sendMessageToActiveTab(responseData);
        );


function sendMessageToActiveTab(responseData) 
    var msg = new Object();
    msg.message = "receiveOrders";
    msg.orderList = JSON.parse(Http.responseText);
    chrome.tabs.query(active: true, currentWindow: true, function(tabs) 
        chrome.tabs.sendMessage(tabs[0].id, msg);
    );

最后在内容脚本中:

chrome.runtime.onMessage.addListener(function(message, callback) 
  if( message.message == "receiveOrders") 
     receiveOrderList(message.orderList);
  
  return;
);

【讨论】:

【参考方案3】:

如中所述 https://developers.google.com/web/updates/2020/07/chrome-85-deps-rems

chrome 将拒绝不安全的 SameSite=None cookie

不再支持在 SameSite 设置为 None 且没有 Secure 属性的情况下使用 cookie。任何请求 SameSite=None 但未标记为 Secure 的 cookie 都将被拒绝。此功能于 2020 年 7 月 14 日开始向稳定版 Chrome 的用户推出。有关完整时间线和详细信息,请参阅 SameSite 更新。通过明文渠道传递的 Cookie 可能会被网络攻击者编目或修改。要求对用于跨站点使用的 cookie 进行安全传输可以降低这种风险。

【讨论】:

以上是关于最新 Chrome 85 更新后的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

最新的 Chrome 85 使用 SameSite=None 和安全删除 3rd 方 cookie

使用 Youtube Iframe API 创建的视频播放器停止使用 Chrome v.85

WebApi 2.2 + Chrome = CORS 405 错误

节点中带有 chrome 50.0.2661.86 的 CORS

Angular 应用程序仅在 chrome 中出现 CORS 错误

Angular 10 PWA 中 Chrome 更新后的新警告“无法安装站点:页面无法脱机工作。从 Chrome 93 开始...”