txc/cors-psr7

框架无关(PSR-7)的 CORS 实现(www.w3.org/TR/cors/)

v1.0.0 2023-09-13 11:31 UTC

This package is auto-updated.

Last update: 2024-09-13 13:28:51 UTC


README

codecov License

为什么创建分支?

由于 neomerx/cors-psr7 不支持 PHP 8.1+,我创建了分支并更新了它以支持此版本。

此包将取代 neomerx/cors-psr7,因此与例如 middlewares/cors 的使用只需包含此包即可。

{
  "require": {
    ...
    "txc/cors-psr7": "^1.0",
    "middlewares/cors": "^2.0",
    ...
  },
}

Code Coverage License

描述

此包具有框架无关的 跨源资源共享(CORS)实现。它符合 PSR-7 HTTP 消息接口。

为什么是这个包?

示例用法

该包设计为用作中间件。典型用法

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 兼容的 Logger 设置为 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)。请参阅许可证文件获取更多信息。