rossaddison/yii-middleware

dev-master 2024-08-08 10:33 UTC

This package is auto-updated.

Last update: 2024-09-08 10:39:18 UTC


README

Yii

Yii 中间件


Latest Stable Version Total Downloads Build status Code Coverage Mutation testing badge static analysis type-coverage psalm-level

该包提供了实现 PSR-15 的中间件类。

对于与代理相关的中间件,有一个单独的包 - Yii 代理中间件

有关如何在 Yii 框架 中使用中间件的更多信息,请参阅 Yii 中间件指南

要求

  • PHP 8.0 或更高版本。

安装

该包可以使用 Composer 安装。

composer require yiisoft/yii-middleware

通用用法

所有类都是 PSR 15 中间件的独立实现,彼此之间没有任何交互。

强制安全连接

将不安全的 HTTP 请求重定向到 HTTPS,并添加增强安全策略所需的首部。

use Yiisoft\Yii\Middleware\ForceSecureConnection;

/**
 * @var Psr\Http\Message\ResponseFactoryInterface $responseFactory
 * @var Psr\Http\Message\ServerRequestInterface $request
 * @var Psr\Http\Server\RequestHandlerInterface $handler
 */

$middleware = new ForceSecureConnection($responseFactory);

// Enables redirection from HTTP to HTTPS:
$middleware = $middleware->withRedirection(301);
// Disables redirection from HTTP to HTTPS:
$middleware = $middleware->withoutRedirection();

$response = $middleware->process($request, $handler);

“内容安全策略” (CSP) 首部可以强制浏览器仅通过安全连接加载页面资源,即使页面布局中指定的链接使用了未受保护的协议。

$middleware = $middleware->withCSP('upgrade-insecure-requests; default-src https:');
// Or without the `Content-Security-Policy` header in response:
$middleware = $middleware->withoutCSP();

中间件在每个响应中添加 HTTP Strict-Transport-Security (HSTS) 首部。该首部告诉浏览器您的站点仅使用 HTTPS。

$maxAge = 3600; // Default is 31_536_000 (12 months).
$subDomains = false; // Whether to add the `includeSubDomains` option to the header value.

$middleware = $middleware->withHSTS($maxAge, $subDomains);
// Or without the `Strict-Transport-Security` header in response:
$middleware = $middleware->withoutHSTS();

HTTP 缓存

通过利用 Last-ModifiedETag HTTP 首部实现客户端缓存。

use Yiisoft\Yii\Middleware\HttpCache;

/**
 * @var Psr\Http\Message\ServerRequestInterface $request
 * @var Psr\Http\Server\RequestHandlerInterface $handler
 */

$middleware = new HttpCache();

// Specify callable that generates the last modified:
$middleware = $middleware->withLastModified(function (ServerRequestInterface $request, mixed $params): int {
    $defaultLastModified = 3600;
    // Some actions.
    return $defaultLastModified;
});
// Specify callable that generates the ETag seed string:
$middleware = $middleware->withEtagSeed(function (ServerRequestInterface $request, mixed $params): string {
    $defaultEtagSeed = '33a64df551425fcc55e4d42a148795d9f25f89d4';
    // Some actions.
    return $defaultEtagSeed;
});

$response = $middleware->process($request, $handler);

此外,您还可以指定以下选项

// Extra parameters for ETag seed string generation:
$middleware = $middleware->withParams(['parameter' => 'value']);

// The value of the `Cache-Control` HTTP header:
$middleware = $middleware->withCacheControlHeader('public, max-age=31536000');
// Default is `public, max-age=3600`. If null, the header won't be sent.

// Enable weak ETags generation (disabled by default):
$middleware = $middleware->withWeakTag();
// You should use weak ETags if the content is semantically equal, but not byte-equal.

IP 过滤器

IpFilter 仅允许从指定的 IP 范围访问,并对于所有其他 IP 返回 403 响应。

use Yiisoft\Yii\Middleware\IpFilter;

/**
 * @var Psr\Http\Message\ResponseFactoryInterface $responseFactory
 * @var Psr\Http\Message\ServerRequestInterface $request
 * @var Psr\Http\Server\RequestHandlerInterface $handler
 * @var Yiisoft\Validator\Rule\ValidatorInterface $validator
 */

// Name of the request attribute holding client IP:
$clientIpAttribute = 'client-ip';
// If there is no such attribute, or it has no value, then the middleware will respond with 403 forbidden.
// If the name of the request attribute is `null`, then `REMOTE_ADDR` server parameter is used to determine client IP.

$middleware = new IpFilter($validator, $responseFactory, $clientIpAttribute);

// Change client IP validator:
$middleware = $middleware->withValidator($validator);

$response = $middleware->process($request, $handler);

重定向

生成并添加一个 Location 首部到响应中。

use Yiisoft\Yii\Middleware\Redirect;

/**
 * @var Psr\Http\Message\ResponseFactoryInterface $responseFactory
 * @var Psr\Http\Message\ServerRequestInterface $request
 * @var Psr\Http\Server\RequestHandlerInterface $handler
 * @var Yiisoft\Router\UrlGeneratorInterface $urlGenerator
 */

$middleware = new Redirect($ipValidator, $urlGenerator);

// Specify URL for redirection:
$middleware = $middleware->toUrl('/login');
// Or specify route data for redirection:
$middleware = $middleware->toRoute('auth/login', ['parameter' => 'value']);
// If you have set a redirect URL with "toUrl()" method, the middleware ignores the route data, since the URL is a
// priority.

$response = $middleware->process($request, $handler);

您还可以设置重定向响应代码的状态。

// For permanent redirection (301):
$middleware = $middleware->permanent();

// For temporary redirection (302):
$middleware = $middleware->permanent();

// Or specify the status code yourself:
$middleware = $middleware->withStatus(303);

子文件夹

支持当应用程序的入口点不在 webroot 直接时进行路由。默认情况下,它根据服务器参数确定 webroot。

信息:您应该在中间件列表中将此中间件放置在 Route 中间件之前。

如果您希望应用程序在指定的路径上运行,请使用前缀

use Yiisoft\Yii\Middleware\Subfolder;

/**
 * @var Psr\Http\Message\ServerRequestInterface $request
 * @var Psr\Http\Server\RequestHandlerInterface $handler
 * @var Yiisoft\Aliases\Aliases $aliases
 * @var Yiisoft\Router\UrlGeneratorInterface $urlGenerator
 */
 
// URI prefix the specified immediately after the domain part (default is `null`):
$prefix = '/blog';
// The prefix value usually begins with a slash and must not end with a slash.

$middleware = new Subfolder($urlGenerator, $aliases, $prefix);

$response = $middleware->process($request, $handler);

标记请求

使用随机值标记请求,该值可用于以后的识别。

use Yiisoft\Yii\Middleware\TagRequest;

/**
 * @var Psr\Http\Message\ServerRequestInterface $request
 * @var Psr\Http\Server\RequestHandlerInterface $handler
 */

$middleware = new TagRequest();
// In the process, a request attribute with the name `requestTag`
// and the generated value by the function `uniqid()` will be added.
$response = $middleware->process($request, $handler);

地区

支持基于地区的路由并配置 URL 生成器。

信息:您应该在中间件列表中将此中间件放置在 Route 中间件之前。

use Yiisoft\Yii\Middleware\Locale;

// Available locales.
$locales = ['en' => 'en-US', 'ru' => 'ru-RU', 'uz' => 'uz-UZ']
/**
 * Specify supported locales.
 * 
 * @var Locale $middleware
 */
$middleware = $middleware->withSupportedLocales($locales);

// Ignore requests which URLs that match "/api**" wildcard pattern.
$middleware = $middleware->withIgnoredRequestUrlPatterns(['/api**']);

$response = $middleware->process($request);

查找的优先级如下

  1. URI 查询路径,即 /de/blog
  2. URI 查询参数名称,即 /blog?_language=de。您可以通过 withQueryParameterName() 自定义参数名称。
  3. 名为 _language 的 Cookie。您可以通过 withCookieName() 自定义名称。
  4. Accept-Language 首部。默认情况下未启用。使用 withDetectLocale(true) 启用它。

默认情况下,找到的地区不会保存。它可以保存到 Cookie 中

use Yiisoft\Yii\Middleware\Locale;

/** @var Locale $middleware */
$middleware = $middleware
    ->withCookieDuration(new DateInterval('P30D')) // Key parameter for activating saving to cookies.
    // Extra customization.
    ->withCookieName('_custom_name')
    ->withSecureCookie(true)

要配置更多服务,例如翻译器或会话,请使用 SetLocaleEvent(需要 Yii 事件调度器)。

use Yiisoft\Translator\TranslatorInterface;
use Yiisoft\Yii\Middleware\Event\SetLocaleEvent;

final class SetLocaleEventHandler
{
    public function __construct(
        private TranslatorInterface $translator
    ) {
    }

    public function handle(SetLocaleEvent $event): void
    {
        $this->translator->setLocale($event->getLocale());
    }
}

注意:使用翻译器需要 Yii 消息翻译器

CORS 允许所有

向响应中添加 CORS 首部。

文档

如果您需要帮助或有任何问题,您可以访问Yii 论坛,那里是一个很好的寻求帮助的地方。您还可以查看其他Yii 社区资源

许可证

Yii 中间件是免费软件。它根据BSD许可证条款发布。有关更多信息,请参阅LICENSE

Yii 软件维护。

支持项目

Open Collective

关注更新

Official website Twitter Telegram Facebook Slack