Laravel 5.5 Middleware
Middleware(中介軟體)
// 請求之前/之後的中介軟體
一箇中間件是請求前還是請求後執行取決於中介軟體本身。比如,以下中介軟體會在請求處理前執行一些任務:
<?php namespace App\Http\Middleware; use Closure; class BeforeMiddleware { public function handle($request, Closure $next) { // 執行動作 return $next($request); } }
而下面這個中介軟體則會在請求處理後執行其任務:
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware
{
public function handle($request, Closure $next)
{
$response = $next($request);
// 執行動作
return $response;
}
}
// 註冊中介軟體
(全域性中介軟體)
如果你想要定義的中介軟體在每一個 HTTP 請求時都被執行,只需要將相應的中介軟體類新增到 app/Http/Kernel.php 的陣列屬性 $middleware 中即可,但除非真的需要,否則我們一般不會把業務級別的中介軟體放到全域性中介軟體中。
(分配中介軟體到指定路由)
如果你想要分配中介軟體到指定路由,首先應該在 app/Http/Kernel.php 檔案中分配給該中介軟體一個 key,預設情況下,該類的 $routeMiddleware 屬性包含了 Laravel 自帶的中介軟體,要新增你自己的中介軟體,只需要將其追加到後面併為其分配一個 key,例如:
/**
* 應用的路由中介軟體列表
*
* 這些中介軟體可以分配給路由組或者單個路由
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'token' => CheckToken::class // 自己新增的中介軟體
];
(中介軟體組)
有時候你可能想要通過指定一個鍵名的方式將相關中介軟體分到同一個組裡面,這樣可以更方便地將其分配到路由中,這可以通過使用 HTTP Kernel 提供的 $middlewareGroups 屬性實現。
Laravel 自帶了開箱即用的 web 和 api 兩個中介軟體組,分別包含可以應用到 Web 和 API 路由的通用中介軟體:
/**
* 應用的中介軟體組
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
// 中介軟體引數
中介軟體還可以接收額外的自定義引數,例如,如果應用需要在執行給定動作之前驗證認證使用者是否擁有指定的角色,可以建立一個 CheckRole 來接收角色名作為額外引數。
額外的中介軟體引數會在 $next 引數之後傳入中介軟體:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckRole
{
/**
* 處理輸入請求
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string $role
* @return mixed
* translator http://laravelacademy.org
*/
public function handle($request, Closure $next, $role)
{
if (! $request->user()->hasRole($role)) {
// Redirect...
}
return $next($request);
}
}
中介軟體引數可以在定義路由時通過 : 分隔中介軟體名和引數名來指定,多箇中間件引數可以通過逗號分隔:
Route::put('post/{id}', function ($id) {
//
})->middleware('role:editor');
// 終端中介軟體
終端中介軟體,可以理解為一個善後的後臺處理中介軟體。有時候中介軟體可能需要在 HTTP 響應傳送到瀏覽器之後做一些工作,比如,Laravel 內建的 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)
{
// 儲存session資料...
}
}
terminate 方法將會接收請求和響應作為引數。定義了一個終端中介軟體之後,還需要將其加入到 app/Http/Kernel.php 檔案的全域性中介軟體列表中。