作者:拾年之璐 公众号:知行研究院
17.1 什么是中间件
中间件就是当程序接收HTTP 请求时,拦截后进行过滤和处理;
比如当用户登录时,可以通过中间件进行验证比对,错误后让其跳转到登录页面;
框架系统自带了一些中间件,比如之前CSRF 令牌保护,就是中间件实现的;
17.2 中间件的基本使用
系统默认创建了几个中间件,它们在 app\Http\Middleware
中。
1、自定义中间件(前置中间件)
如果创建一个自定义的中间件?可以通过一句命令创建一个check 中间件;
php artisan make:middleware Check //创建一个名为Check的中间件
此时,我们打开创建好的Check 中间件文件,默认有一个handle
的方法,关于该方法,解释如下:
//Handle an incoming request.
//方法名和格式,是固定的。默认的这两个参数,必须存在
public function handle(Request $request, Closure $next)
{
//可以在这里写自己的验证、跳转方法
......
//固定返回格式,让其继续往下执行
return $next($request);
}
接下来,需要对中间件进行注册,才可以在路由上使用。
打开 Http/Kernel.php
文件,在路由配置中间件的区域进行注册:
protected $routeMiddleware = [
//自己添加自定义的中间件
'check' => Check::class, //这种写法,是在最前面有:use App\Http\Middleware\Check;
//下面是系统默认有的中间件
'auth' => \App\Http\Middleware\Authenticate::class,
......
];
接下来,可以在前面的 handle方法
中,写入验证内容:
//方法名和格式,是固定的。默认的这两个参数,必须存在
public function handle($request, Closure $next)
{
//可以在这里写自己的验证、跳转方法
//我们模拟测试,假如登录的id不是1
if ($request->get('id') != 1) {
//跳转至登录页面
return redirect(url('/login'));
}
//固定返回格式,让其继续往下执行
return $next($request);
}
然后,我们就可以在其他的页面,比如后台页面的路由上,添加中间件,进行验证:
Route::get('/admin','LoginController@index')->middleware('check');
上面这种中间件,属于前置中间件
,也就是先拦截Http 请求,再执行主体代码。
2、后置中间件
另一种,就是后置中间件,也就是先执行主体代码
,再拦截处理;
//固定方法,固定格式
public function handle($request, Closure $next)
{
//先执行主体代码
$response = $next($request);
//再进行拦截 Http 请求,做相应处理
echo '我是后置中间件';
//固定格式返回
return $response;
}
3、其他方法
1、在路由中间件,我们可以设置多个中间件,进行调用:
Route::get('/admin','LoginController@index')->middleware('check', 'auth');
2、如果没有在 Http/Kernel.php
配置文件中注册中间件,可以采用完整的类名来进行调用:
Route::get('/admin','LoginController@index')->middleware(\App\Http\Middleware\Check::class);
3、全局中间件:直接配置在Http/Kernel.php
配置文件中的$middleware
属性下,每次执行都必然调用:
//These middleware are run during every request to your application.
protected $middleware = [
//添加自定义的全局中间件
\App\Http\Middleware\Every::class,
//下面是系统自带的默认的全局中间件
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
......
];
4、中间件的核心方法可以有第三个参数,可以在控制器调用时传递;
比如前面的handle方法
,可以写为:
//Handle an incoming request.
//方法名和格式,是固定的。默认的这两个参数,必须存在
public function handle(Request $request, Closure $next, $param)
{
//可以在这里写自己的验证、跳转方法
echo $param;
......
//固定返回格式,让其继续往下执行
return $next($request);
}
然后,在路由中,可以给中间件传递参数
Route::get('/admin','LoginController@index')->middleware('check:abc');
将输出abc
5、中间件组:如果有一些需要固定调用多个中间件,我们可以将它群组
protected $middlewareGroups = [
'mymd' => [
'check'=>\App\Http\Middleware\Check::class,
],
];
6、中间件中可以增加terminate()方法,在中间件响应完之后(return $next),再调用;
public function terminate($request, $response)
{
echo '<br>Http 响应完毕之后再调用我';
}
7、中间件也可以在控制器的构造方法里调用:
public function __construct()
{
$this->middleware('check:abc');
}
这里注意错误跳转会死循环;
以上。