中间件是用来处理和过滤拦截进入应用程序的 HTTP 请求
它就像一层防火墙,在保护着我们的框架内核应用。
通过中间件,我们可以做登录身份验证,路由权限,请求日志等等。而且还不需要入侵 Controller
定义中间件(Middleware)
在app/Http/Middleware
目录新建 SecurityMiddleware.php
安全验证中间件,用来保护后台 Admin 模块
<?php
/**
* SecurityMiddleware.php
*
* 后台模块安全保护中间件
*
* PHP version 7
*
* @category PHP
* @package lumen
* @author W2LE
* @copyright 2018/5/4
*/
namespace App\Http\Middleware;
use Closure;
use App\Models\User;
class SecurityMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// 判断是否为后台 Amdin 模块
if(!$request->is('admin/*')) {
return $next($request);
}
// 获取登陆用户信息
$user = User::find($uid);
// 判断是否为管理员身份
if(!$user->administrator) {
// 非管理员无法访问 Admin 模块
return redirect('/');
}
return $next($request);
}
}
中间件注册
定义好中间件后,我们需要把定义的中间件注册到我们的服务中,Lumen 提供的中间件注册有两种模式
- 全局中间件
- 局部中间件
全局中间件
注册全局中间件后,所有的路由都需要先经过全局中间件处理
app/bootstrap/app
/*
|--------------------------------------------------------------------------
| Register Middleware
|--------------------------------------------------------------------------
|
| Next, we will register the middleware with the application. These can
| be global middleware that run before and after each request into a
| route or middleware that'll be assigned to some specific routes.
|
*/
$app->middleware([
App\Http\Middleware\SecurityMiddleware::class,
]);
// 如果有多个中间件,依次添加即可。
// 中间件执行顺序是从上往下,依次执行
局部中间件
注册
/*
|--------------------------------------------------------------------------
| Register Middleware
|--------------------------------------------------------------------------
|
| Next, we will register the middleware with the application. These can
| be global middleware that run before and after each request into a
| route or middleware that'll be assigned to some specific routes.
|
*/
// 注册一个 admin.security 后台模块安全认证中间件
$app->routeMiddleware([
'admin.security' => App\Http\Middleware\SecurityMiddleware::class,
]);
添加局部中间件,局部中间件需要在路由中指定
$router->get('admin/profile', ['middleware' => 'admin.security', 'Admin\ProfileController@Index']);
前置/后置 中间件(Before / After Middleware)
前置中间件(Before Middleware)
前置中间件意思是在 HTTP 请求进入前经过的中间件
默认情况下,定义的中间件都是前置中间件,如我们上面定义的 SecurityMiddleware
后台安全身份认证中间件。
后置中间件(After Middleware)
后置中间件刚好与前置中间件相对;是指在 HTTP 离开应用后经过的中间件
<?php
/**
* AfterMiddleware.php
*
* PHP version 7
*
* @category PHP
* @package lumen
* @author W2LE
* @copyright 2018/5/3
*/
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// 与前置中间件不同的是,在定义的不同之处
$response = $next($request);
// 在此处理后置中间件的业务逻辑
// 比如设置跨域的 header
header('Access-Control-Allow-Origin:*');
...
return $response;
}
}
简单来说“在 $next
前处理业务就是前置,在之后处理就是后置”。也可以合在一起:
// 前置业务
...
$response = $next($request);
// 后置业务
...
return $response;
给中间件传递参数
在路由中通过 :param
方式添加参数:
$router->get('admin/profile', ['middleware' => 'admin.security:safe', 'Admin\ProfileController@Index']);
参数获取:需要在中间件handle
方法中添加接收参数
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param $param 用来接收 route 中传递的参数
* @return mixed
*/
public function handle($request, Closure $next,$param)
{
if($param == 'safe') {
// 处理业务
}
}