neomerx / cors-psr7
框架无关(PSR-7)的CORS实现(www.w3.org/TR/cors/)
Requires
- php: >=8.0.0
- psr/http-message: ^1.0
- psr/log: ^3.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.11
- mockery/mockery: ^1.0
- phpunit/phpunit: ^9.2
- scrutinizer/ocular: ^1.4
- squizlabs/php_codesniffer: ^3.0
README
描述
本包提供了框架无关的跨源资源共享(CORS)实现。它符合PSR-7 HTTP消息接口。
为什么选择这个包?
- 实现基于CORS规范。
- 与PSR-7 HTTP消息接口兼容。
- 支持调试模式,带有PSR-3 日志接口。
- 灵活、模块化和可扩展的解决方案。
- 代码质量高。 100% 测试覆盖率。
- 免费软件许可 Apache 2.0。
示例用法
该包旨在作为中间件使用。典型用法
use Neomerx\Cors\Analyzer; use Psr\Http\Message\RequestInterface; use Neomerx\Cors\Contracts\AnalysisResultInterface; class CorsMiddleware { /** * Handle an incoming request. * * @param RequestInterface $request * @param Closure $next * * @return mixed */ public function handle(RequestInterface $request, Closure $next) { $cors = Analyzer::instance($this->getCorsSettings())->analyze($request); switch ($cors->getRequestType()) { case AnalysisResultInterface::ERR_NO_HOST_HEADER: case AnalysisResultInterface::ERR_ORIGIN_NOT_ALLOWED: case AnalysisResultInterface::ERR_METHOD_NOT_SUPPORTED: case AnalysisResultInterface::ERR_HEADERS_NOT_SUPPORTED: // return 4XX HTTP error return ...; case AnalysisResultInterface::TYPE_PRE_FLIGHT_REQUEST: $corsHeaders = $cors->getResponseHeaders(); // return 200 HTTP with $corsHeaders return ...; case AnalysisResultInterface::TYPE_REQUEST_OUT_OF_CORS_SCOPE: // call next middleware handler return $next($request); default: // actual CORS request $response = $next($request); $corsHeaders = $cors->getResponseHeaders(); // add CORS headers to Response $response ... return $response; } } }
设置
分析器接受设置在 Analyzer::instance($settings)
中,必须实现 AnalysisStrategyInterface
。您可以使用默认实现 \Neomerx\Cors\Strategies\Settings
来设置分析器。
例如,
use Neomerx\Cors\Strategies\Settings; $settings = (new Settings()) ->setServerOrigin('https', 'api.example.com', 443) ->setPreFlightCacheMaxAge(0) ->setCredentialsSupported() ->setAllowedOrigins(['https://www.example.com', ...]) // or enableAllOriginsAllowed() ->setAllowedMethods(['GET', 'POST', 'DELETE', ...]) // or enableAllMethodsAllowed() ->setAllowedHeaders(['X-Custom-Header', ...]) // or enableAllHeadersAllowed() ->setExposedHeaders(['X-Custom-Header', ...]) ->disableAddAllowedMethodsToPreFlightResponse() ->disableAddAllowedHeadersToPreFlightResponse() ->enableCheckHost(); $cors = Analyzer::instance($settings)->analyze($request);
设置可以缓存以提高性能。如果您已经配置了如上所示的设置,您可以得到内部设置状态如下
/** @var array $dataToCache */ $dataToCache = $settings->getData();
应使用缓存状态
$settings = (new Settings())->setData($dataFromCache); $cors = Analyzer::instance($settings)->analyze($request);
安装
composer require neomerx/cors-psr7
调试模式
调试日志将提供如何处理请求的详细步骤描述。为了激活它,需要设置一个PSR-3 兼容的日志器到 Analyzer
。
/** @var \Psr\Log\LoggerInterface $logger */ $logger = ...; $analyzer = Analyzer::instance($settings); $analyzer->setLogger($logger) $cors = $analyzer->analyze($request);
高级用法
处理跨源和同源请求的可能策略有很多,这些策略可能或可能不依赖于请求中的数据。
此内置策略 Settings
实现了对所有请求都相同的简单设置(相同的允许源列表,相同的允许方法等)。
然而,您可以自定义这种行为。例如,您可以根据请求发送不同的允许方法集合。当您拥有某种类型的访问控制系统并希望根据请求(例如其源)区分响应时,这可能很有用。您可以从头实现 AnalysisStrategyInterface
或者在需要时覆盖 Settings
类中的方法。新策略可以发送到 Analyzer
构造函数,或者可以使用 Analyzer::instance
方法进行注入。
示例
class CustomMethodsSettings extends Settings { public function getRequestAllowedMethods(RequestInterface $request): string { // An external Access Control System could be used to determine // which methods are allowed for this request. return ...; } } $cors = Analyzer::instance(new CustomMethodsSettings())->analyze($request);
测试
composer test
有疑问?
不要犹豫,检查 问题 或发布一个新的。
贡献
如果您发现了与CORS 建议书不一致的任何合规性问题,请发布 问题。欢迎使用对文档和代码改进(PSR-2、测试)的拉取请求。
版本管理
本包使用 语义版本控制。
许可证
Apache许可证(版本2.0)。请参阅许可文件获取更多信息。