Lumen 6 中文文档 中间件
介绍
HTTP 中间件为即将进入应用程序的请求提供了一种方便的过滤机制。例如,Lumen 包含一个验证用户是否已通过认证的中间件。如果用户未通过认证,中间件将重定向到登录页面。如果用户已经通过认证,那么该中间件将允许请求进一步进入应用程序。
当然了,除了身份验证外,还可以自定义中间件来执行更多的任务。CORS 中间件将会在返回响应时添加合适的头信息。日志中间件记录进入应用程序的请求。
所有的中间件都放置在 app/Http/Middleware
目录中。
自定义中间件
可以复制 Lumen 应用中自带的 ExampleMiddleware
来创建一个新的中间件。这里我们定义允许 age
大于200的请求进一步传递到应用程序中,否则重定向到 “home” URI。
<?php
namespace App\Http\Middleware;
use Closure;
class OldMiddleware
{
/**
* Run the request filter.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->input('age') <= 200) {
return redirect('home');
}
return $next($request);
}
}
如你所见,如果 age
小于等于 200
,中间件会将本次请求重定向到客户端。否则,该请求将进一步传递到应用程序中。允许请求进一步进入应用程序,只需使用 $request 调用 $next 回调即可。
最好将「中间件」设想为 HTTP 请求到达您的应用程序所必须经过的一系列「层」。每一层都可以检查请求,甚至完全拒绝它。
Before / After 中间件
中间件在请求被处理之前还是之后执行,完全取决于中间件自身。例如,下面的中间件将会在请求被应用程序处理之前执行一些任务操作。
<?php
namespace App\Http\Middleware;
use Closure;
class BeforeMiddleware
{
public function handle($request, Closure $next)
{
// Perform action
return $next($request);
}
}
接下来,这个中间件将会在请求被应用程序处理之后执行一些任务操作。
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware
{
public function handle($request, Closure $next)
{
$response = $next($request);
// Perform action
return $response;
}
}
注册中间件
全局中间件
如果你希望中间件在应用处理每个 HTTP 请求期间运行,只需要将该中间件的类添加到 bootstrap/app.php
文件中的 $app->middleware()
方法即可:
$app->middleware([
App\Http\Middleware\OldMiddleware::class
]);
为路由分配中间件
如果你想为特定路由指定中间件,就应该在 bootstrap/app.php
文件中的 $app->routeMiddleware()
方法中注册中间件的同时为中间件起一个简短的别名:
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
]);
一旦你在HTTP内核中定义了中间件后,就可以在路由的可选数组中使用该中间件:
$router->get('admin/profile', ['middleware' => 'auth', function () {
//
}]);
你也可以一次为路由指定多个中间件:
$router->get('/', ['middleware' => ['first', 'second'], function () {
//
}]);
或者,在使用 uses
键指定控制器操作的路由中,添加控制器路由中间件:
$router->get('admin/profile', [
'middleware' => 'auth',
'uses' => 'AdminController@showProfile'
]);
中间件参数
中间件可以接受额外的自定义参数。例如,如果你想在执行相应的操作之前验证经过认证的用户是否拥有给定的「角色」,可以创建一个 RoleMiddleware
中间件,该中间件接受一个角色名称作为额外的参数。
额外的中间件参数将会在中间件参数 $next
之后传入。
<?php
namespace App\Http\Middleware;
use Closure;
class RoleMiddleware
{
/**
* Run the request filter.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string $role
* @return mixed
*/
public function handle($request, Closure $next, $role)
{
if (! $request->user()->hasRole($role)) {
// Redirect...
}
return $next($request);
}
}
在定义路由时,可以通过用 :
分隔中间件名称和参数来指定中间件参数。多个参数应以逗号分隔:
$router->put('post/{id}', ['middleware' => 'role:editor', function ($id) {
//
}]);
Terminable 中间件
有时候我们在 HTTP 响应发送浏览器之后,还需要做一些操作。例如,session 中间件就是在响应发送浏览器之后才存储 session 数据的。要实现这一点,只需要在中间件中添加一个 terminate
方法即可:
<?php
namespace Illuminate\Session\Middleware;
use Closure;
class StartSession
{
public function handle($request, Closure $next)
{
return $next($request);
}
public function terminate($request, $response)
{
// Store the session data...
}
}
terminate
方法接受两个参数,一个是请求实例,一个是响应实例。不过我们需要将 terminate 中间件添加到 bootstrap/app.php
文件的全局中间件列表中。
当调用 terminate
方法时,Lumen 将会从服务容器中解析出一个全新的中间件实例。如果在中间件的 handle
和 terminate
方法中使用相同的中间件实例,需要通过容器的 singleton
方法在容器中注册中间件。