具有 PHP 标头的跨域请求标头 (CORS)

2022-08-30 01:07:13

我有一个简单的PHP脚本,我正在尝试跨域CORS请求:

<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
...

然而,我仍然得到错误:

请求标头字段不允许X-Requested-WithAccess-Control-Allow-Headers

我错过了什么?


答案 1

正确处理 CORS 请求需要更多。这是一个将更充分(和正确地)响应的函数。

/**
 *  An example CORS-compliant method.  It will allow any GET, POST, or OPTIONS requests from any
 *  origin.
 *
 *  In a production environment, you probably want to be more restrictive, but this gives you
 *  the general idea of what is involved.  For the nitty-gritty low-down, read:
 *
 *  - https://developer.mozilla.org/en/HTTP_access_control
 *  - https://fetch.spec.whatwg.org/#http-cors-protocol
 *
 */
function cors() {
    
    // Allow from any origin
    if (isset($_SERVER['HTTP_ORIGIN'])) {
        // Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one
        // you want to allow, and if so:
        header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Max-Age: 86400');    // cache for 1 day
    }
    
    // Access-Control headers are received during OPTIONS requests
    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
        
        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
            // may also be using PUT, PATCH, HEAD etc
            header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
        
        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
            header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
    
        exit(0);
    }
    
    echo "You have CORS!";
}

安全说明

根据已批准的源列表检查HTTP_ORIGIN标头。

如果源未获批准,则应拒绝该请求。

请阅读规格。

TL;DR

当浏览器想要执行跨站点请求时,它首先通过对URL的“预检”请求确认这是可以的。通过允许 CORS,您可以告诉浏览器来自此 URL 的响应可以与其他域共享。

CORS 不会保护您的服务器。CORS 试图通过告诉浏览器在与其他域共享响应时应有哪些限制来保护您的用户。通常,这种共享是完全禁止的,因此CORS是一种在浏览器的正常安全策略中戳破漏洞的方法。这些孔应该尽可能小,因此请始终根据某种内部列表检查HTTP_ORIGIN。

这里存在一些危险,特别是如果URL提供的数据通常受到保护。您有效地允许源自其他服务器上的浏览器内容读取(并可能操作)服务器上的数据。

如果您要使用CORS,请仔细阅读协议(它很小),并尝试了解您在做什么。为此,代码示例中给出了一个引用 URL。

标头安全性

已经观察到HTTP_ORIGIN标头是不安全的,这是事实。事实上,所有HTTP标头对于该术语的不同含义都是不安全的。除非标头包含可验证的签名/hmac,或者整个会话都是通过 TLS 进行身份验证的,否则标头只是“浏览器告诉我的内容”。

在这种情况下,浏览器说“来自域X的对象想要从此URL获取响应。这样可以吗?CORS的要点是能够回答,“是的,我会允许的”。


答案 2

我得到了同样的错误,并在我的后端脚本中使用以下PHP修复了它:

header('Access-Control-Allow-Origin: *');

header('Access-Control-Allow-Methods: GET, POST');

header("Access-Control-Allow-Headers: X-Requested-With");