Defining Middleware
- Tạo middleware thông qua command line:
php artisan make:middleware EnsureTokenIsValid
Middleware & Responses
- Chúng ta có thể định nghĩa before Middleware để xử lý các logic trước khi check 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; }
}
Registering Middleware
- Middleware có 2 loại: Global và local middleware
Global Middleware
- Nếu muốn đăng ký 1 global middleware thì bạn chỉ cần thêm middleware vào mảng
$middleware
trong file app/Http/Kernel.php
protected $middleware = [ \App\Http\Middleware\TrustProxies::class, \Illuminate\Http\Middleware\HandleCors::class, \App\Http\Middleware\PreventRequestsDuringMaintenance::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ];
Assigning Middleware To Routes
- Đăng ký route middleware bạn cần 2 bước:
- Đăng ký middleware vào mảng
routeMiddleware
trong app/Http/Kernel.php
- Sử dụng tại route
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, 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
Route::get('/profile', function () {
})->middleware('auth');
- Có thể thêm nhiều middleware cho cùng 1 route
Route::get('/', function () {
})->middleware(['first', 'second']);
- Hoặc có thể dùng tên class của middleware để đăng ký:
use App\Http\Middleware\EnsureTokenIsValid; Route::get('/profile', function () {
})->middleware(EnsureTokenIsValid::class);
Excluding Middleware
- Khi đăng ký middleware group route, đôi khi bạn cần loại bỏ middleware cho 1 route nào đó thì có thể sử dụng method
withoutMiddleware
use App\Http\Middleware\EnsureTokenIsValid; Route::middleware([EnsureTokenIsValid::class])->group(function () { Route::get('/', function () { }); Route::get('/profile', function () { })->withoutMiddleware([EnsureTokenIsValid::class]);
});
- Hoặc bạn cũng có thể loại bỏ middleware theo group route:
use App\Http\Middleware\EnsureTokenIsValid; Route::withoutMiddleware([EnsureTokenIsValid::class])->group(function () { Route::get('/profile', function () { });
});
withoutMiddleware
chỉ có thể loại bỏ route middleware không thể loại bỏ global middleware
Middleware Groups
- Đôi khi bạn muốn nhóm nhiều middleware thành group để dễ dàng sử dụng cho các route, bạn có thể thêm các group trong mảng
$middlewareGroups
trong file HTTP kernel.
- Mặc định laravel có 2 group middleware là
web
và api
, 2 middleware group này sẽ tự động được áp dụng vào ứng dụng của bạn thông qua App\Providers\RouteServiceProvider
tương ứng với các route web
và api
:
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, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ],
];
- Middleware group cũng có thể được gán cho các route bằng cách sử dụng cú pháp giống như các middware riêng lẻ khác:
Route::get('/', function () {
})->middleware('web'); Route::middleware(['web'])->group(function () {
});
Sorting Middleware
- Hiếm khi, bạn muốn middleware thực thi theo 1 thứ tự nhất định thì bạn nên kiểm soát chúng trong mảng thuộc tính
$middlewarePriority
:
protected $middlewarePriority = [ \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class, \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class, \Illuminate\Routing\Middleware\ThrottleRequests::class, \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class, \Illuminate\Contracts\Session\Middleware\AuthenticatesSessions::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class,
];
Middleware Parameters
- Middleware cũng có thể nhận tham số vào để xử lý, các tham số dduwwocj truyền vào middleware đứng sau tham số $next:
<?php namespace App\Http\Middleware; use Closure; class EnsureUserHasRole
{ public function handle($request, Closure $next, $role) { if (! $request->user()->hasRole($role)) { } return $next($request); } }
Route::put('/post/{id}', function ($id) {
})->middleware('role:editor');
Terminable Middleware
- Trong trường hợp các bạn cần xử lý logic sau khi HTTP response đã được gửi đến trình duyệt, bạn có thể dùng method
terminate
trong class Middleware:
- Method
terminate
có 2 tham số $request
và $response
<?php namespace Illuminate\Session\Middleware; use Closure; class TerminatingMiddleware
{ public function handle($request, Closure $next) { return $next($request); } public function terminate($request, $response) { }
}
- Khi method
terminate
được gọi, Laravel sẽ xóa instance cũ của middleware và xử lý logic trong method terminate
trên 1 instance mới, nếu bạn muốn gọi method handle
và terminate
trên cùng 1 phiên bản instance thì bạn cần đăng ký middleware với service container bằng method singleton
trong AppServiceProvider
use App\Http\Middleware\TerminatingMiddleware;
public function register()
{ $this->app->singleton(TerminatingMiddleware::class);
}