monstrum / zfr-cors
Zend Framework 模块,让您处理 CORS 请求
Requires
- php: ^7.0
- laminas/laminas-eventmanager: ^2.6.4 || ^3.2.1
- laminas/laminas-http: ^2.10
- laminas/laminas-mvc: ^2.7.15 || ^3.1.1
- laminas/laminas-servicemanager: ^2.7.9 || ^3.4.0
Requires (Dev)
- laminas/laminas-i18n: ^2.9
- laminas/laminas-log: ^2.10
- laminas/laminas-modulemanager: ^2.7.2
- laminas/laminas-serializer: ^2.8
- laminas/laminas-view: ^2.8.1
- pdepend/pdepend: 2.5.*
- php-coveralls/php-coveralls: ^2.1
- phploc/phploc: 5.*
- phpmd/phpmd: 2.6.*
- phpunit/phpunit: ^7.5.18 || ^8.5.1
- sebastian/phpcpd: 4.*
- squizlabs/php_codesniffer: ^3.4
README
ZfrCors 是一个简单的 ZF2 模块,可以帮助您处理跨源资源共享(CORS)。
什么是 ZfrCors ?
ZfrCors 是一个允许轻松配置 ZF 2 应用程序以自动构建遵循 CORS 文档的 HTTP 响应的 Zend Framework 2 模块。
安装
通过输入(或将它添加到您的 composer.json
文件)来安装模块
$ php composer.phar require monstrum/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 在 MvcEvent::EVENT_ROUTE
事件中注册了 ZfrCors\Mvc\CorsRequestListener
,优先级为 -1。这意味着该监听器将在路由匹配之后执行。
配置模块
默认情况下,所有选项都是全局设置,适用于所有路由
allowed_origins
: (数组) 允许的来源列表。要允许任何来源,您可以使用通配符 (*
) 字符。如果指定了多个来源,ZfrCors 将自动检查"Origin"
标头的值,并仅在响应头"Allow-Access-Control-Origin"
中返回允许的域(如果有的话)。要允许任何子域,可以在域前加上通配符字符(即*.example.com
)。请注意,您不需要添加您的宿主 URI(因此,如果您的网站托管为 "example.com",则 "example.com" 会自动允许)。allowed_methods
: (数组) 允许的 HTTP 方法列表。这些方法将在预检请求中返回,以指示哪些方法可以由用户代理执行。您甚至可以指定自定义 HTTP 动词。allowed_headers
: (数组) 返回给预检请求的允许的标头列表。这表示在执行实际请求时允许发送哪些标头。max_age
: (整型) 预检请求应被用户代理缓存的最大年龄(秒)。这防止用户代理为每个请求发送预检请求。exposed_headers
: (数组) 允许在用户代理中读取的响应标头列表。请注意,一些浏览器没有正确实现此功能。allowed_credentials
: (布尔型) 如果为 true,则允许浏览器在请求中发送 cookies。
如果您想配置特定路由,您可以将 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 响应,ZfrCors 将根据您的配置发送适当的标头。响应将以 200 状态码(OK)发送。
请注意,这也会阻止后续的MVC步骤执行,因为所有后续的MVC步骤都将跳过,直到Zend\Mvc\MvcEvent::EVENT_FINISH
,该事件负责实际发送响应。
实际请求
当发起实际请求时,ZfrCors首先检查源是否允许。如果不允许,则创建并发送一个带有403状态码(禁止)的新响应。
请注意,这也会阻止后续的MVC步骤执行,因为所有后续的MVC步骤都将跳过,直到Zend\Mvc\MvcEvent::EVENT_FINISH
,该事件负责实际发送响应。
如果源允许,ZfrCors只需向由Zend\Mvc
产生的请求中添加适当的头信息。
安全顾虑
请不要使用此模块来保护您的应用程序!您必须使用适当的授权模块,例如BjyAuthorize、ZfcRbac或SpiffyAuthorize。
ZfrCors仅允许接受或拒绝跨源请求。
自定义方案
在内部,ZfrCors使用Zend\Uri\UriFactory
类。如果您使用自定义方案(例如,如果您使用某些Google Chrome扩展测试您的API),您需要通过将它们添加到UriFactory
配置中来为这些方案添加支持(请参考文档)。
示例
要将chrome-extension
自定义方案注册到您的API中,只需将以下内容添加到module/Application/Module.php
中的onBootstrap()
方法。
UriFactory::registerScheme('chrome-extension', 'Zend\Uri\Uri');
请注意,如果您的IDE没有自动解析,您应该在同一个文件中添加以下use
定义
use Zend\Uri\UriFactory;
以这种方式注册chrome-extension
自定义方案,允许您使用Google Chrome扩展来测试您的API。