使用 Laravel-Cors 根据条件设置 AllowedOrigins

Set AllowedOrigins based on condition using Laravel-Cors

我之前使用自定义 cors 中间件来根据我的环境处理 Allow Origin。但是升级到 5.5 后,我遇到了预检选项 cors 的问题,所以我切换到 laravel-cors 库。但是现在我不知道如何仅通过配置文件来处理不同的情况。我想知道是否有人遇到过类似的问题。这是我之前自定义的cors中间件:

public function handle($request, Closure $next)
{

    $origin = \Config::get('app.url', "https://mysite.ca");

    // Set origin for localhost developing, else just use the staging server
    if( isset( $_SERVER['HTTP_ORIGIN'] ) && $_SERVER['HTTP_ORIGIN'] === 'http://app.localhost:3333' ) {
        $origin = 'http://app.localhost:3333';
    }


    $response = $next($request);


    $response->headers->set('Access-Control-Allow-Origin', $origin);
    $response->headers->set('Access-Control-Expose-Headers','Authorization');
    $response->headers->set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
    $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With, Application');
    $response->headers->set('Access-Control-Allow-Credentials','true');

    return $response;
}

laravel-cors 默认情况下已经自动执行与问题中的自定义代码相同的操作——也就是说,laravel-cors 有条件地根据的值设置 Access-Control-Allow-OriginOrigin header 是,如果您在配置中允许它。

但是,就问题中代码的作用而言,尚不清楚为什么要发送 Access-Control-Allow-Origin 响应 header 并将其值设置为 app.url值。

我的意思是,app.url 的值是您安装 laravel-cors 的同一台服务器的 URL,对吗?也就是说,它是您要允许来自特定来源的 cross-origin 请求的应用程序。 如果是这种情况,那么您不需要明确允许来自 app.url 的请求,因为 这些不是 cross-origin 请求,所以您不需要做任何事情就已经允许了它们.

另一点是 app.url 不是原点——而是 URL,可能有路径。但是起源没有路径。所以你实际上不想将 $origin 的值设置为 app.url 除非你确定你的 app.url 没有路径(甚至没有尾随斜线)。

综上所述,如果您真的想获得问题中自定义代码的确切行为,您可以将 $origin 变量设置为全局变量,然后设置 allowedOrigins 数组像这样:

return [
     /*
     |--------------------------------------------------------------------------
     | Laravel CORS
     |--------------------------------------------------------------------------
     |
     | allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
     | to accept any value.
     |
     */
    'supportsCredentials' => true,
    'allowedOrigins' => [$origin, 'http://app.localhost:3333'],
    'allowedHeaders' => ['Content-Type', 'Accept', 'Authorization', 'X-Requested-With', 'Application'],
    'allowedMethods' => ['POST', 'GET', 'OPTIONS', 'PUT', 'DELETE'],
    'exposedHeaders' => ['Authorization'],
    'maxAge' => 0,
]

这些是完成与问题中的自定义代码等效的配置设置。

给定上面的 allowedOrigins 值,条件逻辑 laravel-cors 如下:

  • 如果 Origin request-header 值与 $origin 的值匹配,则发回响应 header Access-Control-Allow-Origin 并将其值设置为 $origin价值
  • 否则如果Originrequest-header值为http://app.localhost:3333,则发回响应headerAccess-Control-Allow-Origin: http://app.localhost:3333
  • 否则不要发回任何 Access-Control-Allow-Origin 响应 header

如果您想要允许来自 $originhttp://app.localhost:3333 的值的 cross-origin 请求,但不允许来自任何其他来源的请求,这就是您所需要的。

确实与问题中的自定义代码做了一些不同的事情——因为问题中的代码导致 Access-Control-Allow-Origin 响应 header 和 $origin价值甚至被发回不允许的来源。

但无论如何你都不想那样做。如果请求来自不允许的来源,则根本没有必要发回任何 Access-Control-Allow-Origin header — 因为缺少 Access-Control-Allow-Origin 响应 header告诉浏览器 “不允许前端 JavaScript 代码 运行 在这个来源访问来自我们服务器的响应”.

除此之外,公开泄露任何允许来源的信息毫无意义——如果您发送默认 Access-Control-Allow-Origin 响应 header 设置为$origin,正如问题中的自定义代码一样。