4

我正在按照CORS 标准在服务器中实现 CORS 协议。我的问题是当服务器希望拒绝特定的来源时应该如何响应。

我了解在允许 Origin 时如何响应简单和预检请求。但是,对于那些服务器不想允许的 Origin,如何响应呢?我最初的猜测只是不返回任何 CORS 标头,这会导致预检请求失败,如所愿。

该标准在第 3.2.3 节中简要提到了这一点,但这听起来像是在描述一个根本不希望参与 CORS服务器(而不是一个希望参与 CORS 并允许某些 Origin,但不允许其他):

如果服务器不希望参与 CORS 协议,则其对 CORS 或 CORS 预检请求的 HTTP 响应不得包含上述任何标头。鼓励服务器在此类 HTTP 响应中使用 403 状态。

这是响应服务器不想允许的来源的正确方法吗?客户端似乎可能将其误解为“此服务器不允许任何跨源请求”(实际上,问题出在此特定源,而服务器将允许其他源)。

我知道这个问题,但它指的是规范的过时版本,答案似乎并不明确。

4

2 回答 2

1

[a 403 error status] 是响应服务器不想允许的 Origin 的正确方法吗?客户端似乎可能将其误解为“此服务器不允许任何跨源请求”(实际上,问题出在此特定源,而服务器将允许其他源)。

发送请求脚本可能误解的错误代码并没有错。它是 CORS 设计的一部分。为避免混淆浏览器,请务必将标头Vary: Origin与响应一起发送。这告诉客户端的浏览器,如果具有不同来源的脚本试图访问相同的资源,它应该再次检查而不是查找缓存的 CORS 参数。请参阅此处进行一些讨论。

于 2019-03-11T08:43:54.500 回答
0

CORS 默认禁用,因此如果您不希望给定主机获得响应,请不要将它们添加到服务器返回的 CORS Access-Control-Allow-Origin 标头中

访问控制允许来源:https ://www.example.com

如果主机向您的服务器发出请求并且它们未在此标头中列出,则它们将在其预检请求中收到错误响应。

带有 CORS 的 nginx 配置示例如下所示

server {
  listen        80;
  server_name   api.example.com;

  location / {

    # Simple requests
    if ($request_method ~* "(GET|POST)") {
      add_header "Access-Control-Allow-Origin" "https://example.com";
    }

    # Preflighted requests
    if ($request_method = OPTIONS) {
      add_header "Access-Control-Allow-Origin"  "https://example.com";
      add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
      add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
      return 200;
    }

    # Handle request
  }
}

此外,规范中关于预检请求错误的重要说明:

CORS 失败会导致错误,但出于安全原因,JavaScript 代码无法提供有关问题的详细信息。所有代码都知道发生了错误。确定具体出了什么问题的唯一方法是查看浏览器的控制台以获取详细信息。

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

于 2018-07-27T17:26:33.627 回答