apploud/cors-psr7

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

v3.0.3 2024-05-21 07:34 UTC

This package is auto-updated.

Last update: 2024-09-21 08:37:31 UTC


README

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 兼容的日志记录器设置到 Analyzer

/** @var \Psr\Log\LoggerInterface $logger */
$logger   = ...;

$analyzer = Analyzer::instance($settings);
$analyzer->setLogger($logger)
$cors     = $analyzer->analyze($request);

高级用法

有许多处理跨源和同源请求的策略,这些策略可能或可能依赖于请求中的数据。

此内置策略 Settings 实现了适用于所有请求的简单设置(相同的允许来源列表,相同的允许方法等)。

但是,您可以自定义此类行为。例如,您可以根据请求发送不同的允许方法集。当您拥有某种类型的访问控制系统并希望根据请求(例如,根据其来源)区分响应时,这可能很有用。您可以从头开始实现 AnalysisStrategyInterface 或在仅需要对 Settings 进行少量更改的情况下覆盖 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)。有关更多信息,请参阅许可文件