## 中间件 中间件主要用于拦截或过滤应用的请求,并进行必要的业务处理,通常使用在登录验证的场景,基于 [PSR-15](https://www.php-fig.org/psr/psr-15/) 标准实现。 ## 组件 使用 [composer]([https://www.phpcomposer.com/](https://www.phpcomposer.com/)) 安装: ~~~ composer require mix/http-server ~~~ ## 定义中间件 ~~~ <?php namespace App\Http\Middleware; use App\Http\Helpers\ResponseHelper; use Mix\Auth\Authorization; use Mix\Auth\BearerTokenExtractor; use Mix\Http\Message\Response; use Mix\Http\Message\ServerRequest; use Mix\Http\Server\Middleware\MiddlewareInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; /** * Class AuthMiddleware * @package App\Http\Middleware * @author liu,jian <coder.keda@gmail.com> */ class AuthMiddleware implements MiddlewareInterface { /** * @var ServerRequest */ public $request; /** * @var Response */ public $response; /** * @var Authorization */ public $auth; /** * SessionMiddleware constructor. * @param ServerRequest $request * @param Response $response */ public function __construct(ServerRequest $request, Response $response) { $this->request = $request; $this->response = $response; $this->auth = context()->get('auth'); } /** * Process an incoming server request. * * Processes an incoming server request in order to produce a response. * If unable to produce the response itself, it may delegate to the provided * request handler to do so. */ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { // 权限验证 $tokenExtractor = new BearerTokenExtractor($request); try { $payload = $this->auth->getPayload($tokenExtractor); } catch (\Throwable $e) { // 中断执行,返回错误信息 $content = ['code' => 100001, 'message' => 'No access']; $response = ResponseHelper::json($this->response, $content); return $response; } // 把 JWT Payload 放入 Request 的上下文,方便其他位置调用 $context = $this->request->getContext(); $context->payload = $payload; // 继续往下执行 return $handler->handle($request); } } ~~~ ## 注册中间件 定义的中间件需要在路由规则 `middleware` 字段中注册: ``` // 路由规则 'rules' => [ // 普通路由 '/' => [[\App\Http\Controllers\IndexController::class, 'index'], 'middleware' => [\App\Http\Middleware\ActionMiddleware::class]], ], ], ``` ### 全局中间件 全局中间件是全局有效的: ~~~ // 路由 [ // 名称 'name' => 'route', // 类路径 'class' => \Mix\Route\Router::class, // 初始化方法 'initMethod' => 'parse', // 属性注入 'properties' => [ ... // 全局中间件 'middleware' => [\App\Http\Middleware\GlobalMiddleware::class], // 路由规则 'rules' => [ ... ], ], ], ~~~ ### 分组中间件 分组中间件只在该路由分组的规则中有效: ~~~ // 路由 [ // 名称 'name' => 'route', // 类路径 'class' => \Mix\Route\Router::class, // 初始化方法 'initMethod' => 'parse', // 属性注入 'properties' => [ ... // 路由规则 'rules' => [ ... // 分组路由 '/v2' => [ // 分组路由规则 [ ... ], // 分组中间件 'middleware' => [\App\Http\Middleware\GroupMiddleware::class], ], ], ], ], ~~~ 框架骨架代码中默认包含了几个常用中间件: - [AuthMiddleware.php](https://github.com/mix-php/mix-skeleton/blob/master/app/Api/Middleware/AuthMiddleware.php "AuthMiddleware.php") - [SessionMiddleware.php](https://github.com/mix-php/mix-skeleton/blob/master/app/Web/Middleware/SessionMiddleware.php "SessionMiddleware.php") - [CorsMiddleware.php](https://github.com/mix-php/mix-skeleton/blob/master/app/Api/Middleware/CorsMiddleware.php "CorsMiddleware.php")