yiisoft/yii-middleware

1.0.4 2024-09-03 19:34 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 Proxy Middleware

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

要求

  • PHP 8.0 或更高版本。

安装

该包可以使用Composer安装。

composer require yiisoft/yii-middleware

通用用法

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

ForceSecureConnection

将不安全的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);

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

$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();

HttpCache

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

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.

IpFilter

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);

Redirect

在响应中生成并添加一个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);

Subfolder

当应用程序的入口点不是直接在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);

TagRequest

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

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);

Locale

支持基于区域的路由并配置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 Event Dispatcher)。

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 Message Translator

CorsAllowAll

向响应中添加CORS首部。

文档

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

许可证

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

Yii 软件维护。

支持项目

Open Collective

关注更新

Official website Twitter Telegram Facebook Slack