今天來講講laravel好用的功能 middleware(中介層),middleware是laravel非常好用的功能之一,他可以幫你過濾一些request。通常會設置在路由器,當request進入路由後,會先經過你設置的middleware,過濾之後才會到你要的controller。
這功能非常適合做一些登入驗證,或是log之類的工作。就不需要在每個controller開頭都寫一些驗證的code,相當方便。
middleware就像洋蔥一樣,一層又一層覆蓋在你的code,request進來後需要通過一個個中介層,例如A中介層通過後,A會將request丟向B中介層,B通過後可能會丟到C之類的,request必須過關斬將,最後才會到達專案的核心controller。
php artisan make:middleware {file name}
直接使用php artisan 建立一個新的middleware,檔案在app/Http/Middleware裏面
建立好新的middleware了嗎,再來講講其內容,middleware其實分為before以及after。
before就是指再request進來就先經過middleware過濾後再進入到controller。
after指的是先進入controller後,response會經過middleware
以下為官方範例:
<?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;
}
}
有發現不同點嗎,也就是內容稍有不同而已,將你的code寫在// Perform action
的地方吧,比較常用的地方是驗證,例如你可以寫個判斷式,驗證request的內容,若是不符合就過慮掉之類的。
middleware要先註冊才能使用,註冊的地方在app/Http/Kernel.php裏面。
讓我們看看Kernel.php中的內容吧
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
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,
];
/**
* The application's route middleware groups.
*
* @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',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
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,
];
}
上面Kernel.php中的內容,可以看到class中分為3個array分別代表,全域(Global Middleware)、路由、群組。
全域註冊代表所有request都會通過該middleware,路由則是使用再路由設定上才會使request通過。Kernel.php之中還有群組功能,將多個middleware集合成一個群組,並用在路由上。
要註冊很簡單,其實只要依照上面,照著他的格式打就行了,也就是middleware的namespace 再加上class名稱 ::class 就成了,例如:
全域註冊\App\Http\Middleware\BeforeMiddleware::class,
將這段code貼在第一個array中,BeforeMiddleware就完成全域註冊了,簡單吧
群組註冊
基本上都大同小異\App\Http\Middleware\BeforeMiddleware::class,
將上面的code丟到第2個array你要註冊的群組就完成註冊了
路由註冊'name'=>App\Http\Middleware\BeforeMiddleware::class,
將上面的code丟到第3個array中
跟上面都差不多,只是加了自訂的Key,之後配置在route中會用到,設個自己喜歡的名子吧。
範例:
Route::middleware('tokenAuth')->get('user/{email}', 'api\UserController@show');
像上面那樣,將middleware設置在Route,就可以過濾這支Route。(上面的範例使用的tokenAuth是我再註冊時定下的middleware名子)
這個路由設定是我的Todolist route設定中的其中一支,其功能是驗證request有沒有帶驗證用的token,內容會再之後的章節中講到,敬請期待。