zfr/zfr-cors

一个让用户处理CORS请求的Zend Framework模块

v2.0.0 2019-06-18 13:43 UTC

This package is auto-updated.

Last update: 2024-08-29 03:23:44 UTC


README

Build Status Scrutinizer Quality Score Coverage Status Latest Stable Version

ZfrCors 是一个简单的 ZF2 模块,帮助您处理跨源资源共享(CORS)。

什么是 ZfrCors?

ZfrCors 是一个允许轻松配置 ZF 2 应用程序的 Zend Framework 2 模块,以便自动构建遵循 CORS 文档的 HTTP 响应。

安装

通过输入以下命令安装模块(或将其添加到您的 composer.json 文件)

$ php composer.phar require zfr/zfr-cors

然后,通过在您的 application.config.php 文件中添加 "ZfrCors" 来启用它。

默认情况下,ZfrCors 配置为拒绝所有 CORS 请求。要更改此设置,您需要将 config/zfr_cors.global.php.dist 文件复制到您的 autoload 文件夹中(删除 .dist 扩展名),并根据您的需求进行修改。

文档

什么是 CORS?

CORS 是一种机制,允许从您的浏览器执行跨源请求。

例如,假设您的网站托管在 http://example.com 域。默认情况下,出于安全原因,用户代理不允许执行对另一个域的 AJAX 请求(例如 http://funny-domain.com)。

使用 CORS,您可以允许您的服务器回复此类请求。

您可以在网上找到有关 CORS 如何工作的更好文档

事件注册

ZfrCors 将 ZfrCors\Mvc\CorsRequestListener 注册到 MvcEvent::EVENT_ROUTE 事件,优先级为 -1。这意味着此监听器在匹配路由之后执行。

配置模块

默认情况下,所有选项都是全局设置,适用于所有路由

  • allowed_origins:(数组) 允许的源列表。要允许任何源,您可以使用通配符(*)字符。如果指定了多个源,ZfrCors 将自动检查 "Origin" 头的值,并且只在响应头中返回允许的域(如果有的话)。要允许任何子域,可以在域前加上通配符字符(例如 *.example.com)。请注意,您不需要添加您的宿主 URI(因此,如果您的网站托管为 "example.com",则 "example.com" 自动允许)。
  • allowed_methods:(数组) 允许的 HTTP 方法列表。这些方法将在预检请求中返回,以指示哪些方法允许用户代理。您甚至可以指定自定义 HTTP 动词。
  • allowed_headers:(数组) 将返回给预检请求的允许的头部列表。这表示在执行实际请求时,允许用户代理发送哪些头部。
  • max_age:(整数) 预检请求应该在用户代理中缓存的最大年龄(秒)。这可以防止用户代理为每个请求发送预检请求。
  • exposed_headers:(数组) 允许在用户代理中读取的响应头部列表。请注意,一些浏览器可能没有正确实现此功能。
  • allowed_credentials:(布尔值) 如果为 true,则允许浏览器在请求中发送 cookie。

如果您想配置特定的路由,可以在路由配置中添加 ZfrCors\Options\CorsOptions::ROUTE_PARAM

<?php

return [
    'zfr_cors' => [
        'allowed_origins' => ['*'],
        'allowed_methods' => ['GET', 'POST', 'DELETE'],
    ],
    'router' => [
        'routes' => [
            'readOnlyRoute' => [
                'type' => 'literal',
                'options' => [
                    'route' => '/foo/bar',
                    'defaults' => [
                        // This will replace allowed_methods configuration to only allow GET requests
                        // and only allow a specific origin instead of the wildcard origin
                        ZfrCors\Options\CorsOptions::ROUTE_PARAM => [
                            'allowed_origins' => ['http://example.org'],
                            'allowed_methods' => ['GET'],
                        ],
                    ],
                ],
            ],
            'someAjaxCalls' => [
                'type' => 'literal',
                'options' => [
                    'route' => '/ajax',
                    'defaults' => [
                        // This overrides the wildcard origin
                        ZfrCors\Options\CorsOptions::ROUTE_PARAM => [
                            'allowed_origins' => ['http://example.org'],
                        ],
                    ],
                ],
                'may_terminate' => false,
                'child_routes' => [
                    'blog' => [
                        'type' => 'literal',
                        'options' => [
                            'route' => '/blogpost',
                            'defaults' => [
                                // This would only allow `http://example.org` to GET this route
                                \ZfrCors\Options\CorsOptions::ROUTE_PARAM => [
                                    'allowed_methods' => ['GET'],
                                ],
                            ],
                        ],
                        'may_terminate' => true,
                        'child_routes' => [
                            'delete' => [
                                'type' => 'segment',
                                'options' => [
                                    'route' => ':id',
                                    // This would only allow origin `http://example.org` to apply DELETE on this route
                                    'defaults' => [
                                        \ZfrCors\Options\CorsOptions::ROUTE_PARAM => [
                                            'allowed_methods' => ['DELETE'],
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],
];

预检请求

如果ZfrCors检测到预检CORS请求,将会创建一个新的HTTP响应,并根据您的配置发送适当的头部信息。响应将以200状态码(OK)发送。

请注意,这将阻止后续的MVC步骤执行,因为所有后续的MVC步骤都会跳过,直到 Zend\Mvc\MvcEvent::EVENT_FINISH 事件,该事件负责实际发送响应。

实际请求

当发起实际请求时,ZfrCors首先检查来源是否允许。如果不允许,将创建一个新的带有403状态码(禁止)的响应并发送。

请注意,这将阻止后续的MVC步骤执行,因为所有后续的MVC步骤都会跳过,直到 Zend\Mvc\MvcEvent::EVENT_FINISH 事件,该事件负责实际发送响应。

如果来源允许,ZfrCors将只向由 Zend\Mvc 生成的请求添加适当的头部信息。

安全担忧

请勿使用此模块来保护您的应用程序!您必须使用适当的授权模块,如 BjyAuthorizeZfcRbacSpiffyAuthorize

ZfrCors仅允许接受或拒绝跨源请求。

自定义方案

内部,ZfrCors使用Zend\Uri\UriFactory类。如果您使用自定义方案(例如,如果您使用Google Chrome扩展测试您的API),您需要通过将它们添加到UriFactory配置来支持这些方案(请参阅文档)。

示例

要在您的API中注册chrome-extension自定义方案,只需将以下代码添加到module/Application/Module.php中的onBootstrap()方法:

UriFactory::registerScheme('chrome-extension', 'Zend\Uri\Uri');

注意:如果您的IDE无法自动解析此代码,您应在同一文件中添加以下use定义:

use Zend\Uri\UriFactory;

以这种方式注册chrome-extension自定义方案允许您使用Google Chrome扩展来测试API。