- 声明一个中间件
- 定义中间件
- 使用
- 配置全局中间件
- 通过注解使用
- 应用
- 提前拦截请求
- 跨域设置
- 用户JWT登陆验证
声明一个中间件
中间件是用于控制 请求到达 和 响应请求 的整个流程的,通常用于对请求进行过滤验证处理,当你需要对请求或响应作出对应的修改或处理,或想调整请求处理的流程时均可以使用中间件来实现。
定义中间件
只需要实现了 Swoft\Http\Server\Contract\MiddlewareInterface 接口均为一个合法的中间件,其中 process() 方法为该中间件逻辑处理方法。
namespace App\Http\Middleware;use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\RequestHandlerInterface;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Http\Server\Contract\MiddlewareInterface;/*** @Bean()*/class ControllerMiddleware implements MiddlewareInterface{/*** Process an incoming server request.** @param ServerRequestInterface $request* @param RequestHandlerInterface $handler** @return ResponseInterface* @inheritdoc*/public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface{$response = $handler->handle($request);return $response;}}
使用
配置全局中间件
当你的自定义中间件需要全局请求应用,则可以考虑将此中间件作为全局中间件去使用,只需在 Bean 配置文件内配置 httpDispatcher 的 middlewares 属性,在数组中加入你的自定义中间件的命名空间地址,相关配置通常在 app/bean.php 内
return [...'httpDispatcher'=>['middlewares'=>[AuthMiddleware::class,ApiMiddleware::class]]...]
通过注解使用
通过 @Middleware 和 @Middlewares, 可以很方便的配置中间件到当前的 Controller 和 Action 内
当将此注解应用于 Controller 上,则作用域为整个 Controller
将此注解应用于 Action 上,则作用域仅为当前的 Action@Middleware 用于配置单个中间件@Middlewares 显而易见的是用于配置一组 @Middleware,按照定义顺序依次执行
namespace App\Http\Controller;use App\Http\Middleware\ApiMiddleware;use App\Http\Middleware\IndexMiddleware;use App\Http\Middleware\ControllerMiddleware;use Swoft\Http\Server\Annotation\Mapping\Controller;use Swoft\Http\Server\Annotation\Mapping\Middleware;use Swoft\Http\Server\Annotation\Mapping\Middlewares;use Swoft\Http\Server\Annotation\Mapping\RequestMapping;/*** @Controller()* @Middlewares({* @Middleware(ApiMiddleware::class),* @Middleware(ControllerMiddleware::class)* })*/class MiddlewareController{/*** @RequestMapping()* @Middleware(IndexMiddleware::class)*/public function index(){return "MiddlewareController";}}
应用
提前拦截请求
注意: 拦截要在 $handler->handle($request) 之前
namespace App\Http\Middleware;use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\RequestHandlerInterface;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Context\Context;use Swoft\Http\Server\Contract\MiddlewareInterface;/*** @Bean()*/class SomeMiddleware implements MiddlewareInterface{/*** Process an incoming server request.* @param ServerRequestInterface $request* @param RequestHandlerInterface $handler* @return ResponseInterface* @inheritdoc*/public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface{$path = $request->getUri()->getPath();if ($path === '/favicon.ico') {$response = Context::mustGet()->getResponse();return $response->withStatus(404);}return $handler->handle($request);}}
跨域设置
namespace App\Http\Middleware;use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\RequestHandlerInterface;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Http\Server\Contract\MiddlewareInterface;/*** @Bean()*/class CorsMiddleware implements MiddlewareInterface{/*** Process an incoming server request.* @param ServerRequestInterface $request* @param RequestHandlerInterface $handler* @return ResponseInterface* @inheritdoc*/public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface{if ('OPTIONS' === $request->getMethod()) {$response = Context::mustGet()->getResponse();return $this->configResponse($response);}$response = $handler->handle($request);return $this->configResponse($response);}private function configResponse(ResponseInterface $response){return $response->withHeader('Access-Control-Allow-Origin', 'http://mysite')->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');}}
用户JWT登陆验证
namespace App\Http\Middleware;use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\RequestHandlerInterface;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Context\Context;use Swoft\Http\Server\Contract\MiddlewareInterface;/*** @Bean()*/class AuthMiddleware implements MiddlewareInterface{/*** Process an incoming server request.* @param ServerRequestInterface $request* @param RequestHandlerInterface $handler* @return ResponseInterface* @inheritdoc*/public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface{// before request handle// 判断token$token = $request->getHeaderLine("token");$type = \config('jwt.type');$public = \config('jwt.publicKey');try {$auth = JWT::decode($token, $public, ['type' => $type]);$request->user = $auth->user;} catch (\Exception $e) {$json = ['code'=>0,'msg'=>'授权失败']$response = Context::mustGet()->getResponse();return $response->withData($json);}$response = $handler->handle($request);return $response;// after request handle}}
