HTTP 中間件提供了驗證過濾的機制,在請求進入 route 之前,可以先驗證使用者身份或是其他任務,成功後才進入 route。而如果沒有中間件,就必須在每一個 route 重複篩寫程式碼進行驗證工作。 在 laravel 中,所有的中間件都被放在 app/Http/Middleware 目錄之下。
php artisan make:middleware userAuth
利用這個指令建立中間件,可以在 app/Http/Middleware 看到一個名為 userAuth.php 的檔案。
中間件可以在 route 進入前執行,也可以在進入後執行。
namespace App\Http\Middleware;
use Closure;
class userAuth
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}
這種寫法會先讓中間件執行,才讓請求進入 route。
namespace App\Http\Middleware;
use Closure;
class userAuth
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
return $response;
}
}
這種寫法會先把請求傳入 route , route 執行完後才執行中間件。
如果想讓每個 http 請求都經過一個 middleware ,只要將中間件類別名稱加入 app/Http/Kernel.php 的 $middleware 屬性清單列表中即可。
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\userAuth::class,
];
如果要替路由指定中間件,要先在 app/Http/Kernel.php 的 $routeMiddleware 屬性幫中間件設定一個名稱。
$routeMiddleware 屬性已經有 laravel 預設提供的中間件,只要在下面新增自己的中間件即可。
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'userAuth' => \App\Http\Middleware\userAuth::class,
];
想要將多個中間件合為一個的話,可以在 $middlewareGroups 屬性中設定。
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
'auth:api',
],
];
laravel 預設了 web 以及 api 兩個中介群組。
Route::get('admin', 'userController@admin')->middleware('userAuth');
利用 middleware() 方法,參數帶入中間件名稱。
Route::get('admin', 'userController@admin')->middleware('userAuth:webInfo,1');
如果需要將參數帶入中間件,在 middleware() 方法中,除了帶入中間件名稱外,在名稱後方以“ :“ 分隔,加入參數名稱即可,多個參數以逗號分隔。
public function handle($request, Closure $next, $page, $pageNum)
{
}
在中間件部分,在 $next 後面新增要帶入的引數,數量與 route 中的參數對應。
Route::group(['middleware' => ['web']], function () {
//
});
如果指定了多個中間件合為一個,可以使用 group 方法指派。
Route::middleware('auth')->group(function () {
Route::get('/', function () {
// 使用 auth 中間件
});
Route::get('admin', function () {
// 使用 auth 中間件
});
});
如果還記得,我們在 route 介紹的文章當中已經介紹過,如果要讓多個路由都經過同一個中間件,可以使用這個方法。
文章至此告一段落,下一篇將會總結至本篇的所有部分,應當可以設計出一個基本的登入系統。
關於作者
粉絲專頁
文章分類