laravel中間件的使用

簡介
HTTP 中間件提供了爲過濾進入應用的 HTTP 請求提供了一套便利的機制。例如,Laravel 內置了一箇中間件來驗證用戶是否通過受權,若是用戶沒有通過受權,中間件會將用戶重定向到登陸頁面,不然若是用戶通過受權,中間件就會容許請求繼續往前進入下一步操做。php

固然,除了認證以外,中間件還能夠被用來處理更多其它任務。好比:CORS 中間件能夠用於爲離開站點的響應添加合適的頭(跨域);日誌中間件能夠記錄全部進入站點的請求。laravel

Laravel框架自帶了一些中間件,包括維護模式、認證、CSRF 保護中間件等等。全部的中間件都位於 app/Http/Middleware 目錄。web

定義中間件
要建立一個新的中間件,能夠經過 Artisan 命令 make:middleware:api

php artisan make:middleware Test
這個命令會在 app/Http/Middleware 目錄下建立一個新的中間件類 Test跨域

<?php

namespace App\Http\Middleware;

use Closure;

class Test
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}
程序執行前調用的方法數組

public function handle($request, Closure $next, $guard = null)
{
// 執行動做
if(!$request->session()->has('user')){
return redirect("login");
}
return $next($request);
}
程序執行後調用的方法瀏覽器

public function handle($request, Closure $next)
{
$response = $next($request);
// 執行動做
if(!$request->session()->has('huser')){
return redirect("login/index");
}
return $response;
}
全局中間件session

若是你想要中間件在每個 HTTP 請求期間被執行,只須要將相應的中間件類設置到 app/Http/Kernel.php 的數組屬性 $middleware 中便可。app

/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,

];
分配中間件到路由框架

若是你想要分配中間件到指定路由,首先應該在 app/Http/Kernel.php 文件中分配給該中間件一個簡寫的 key,默認狀況下,該類的 $routeMiddleware 屬性包含了 Laravel 內置的入口中間件,添加你本身的中間件只須要將其追加到後面併爲其分配一個 key:

 在 App\Http\Kernel 裏中,添加一行'Test' => \App\Http\Middleware\Test::class,


protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'Test' => \App\Http\Middleware\Test::class,
];
中間件在 HTTP Kernel 中被定義後,可使用 middleware 方法鏈的方式定義路由:

Route::any('test','IndexController@test')->middleware('Test')
中間件組(分組)

有時候你可能想要經過指定一個鍵名的方式將相關中間件分到一個組裏面,從而更方便將其分配到路由中,這能夠經過使用 HTTP Kernel 的 $middlewareGroups  實現。

Laravel 自帶了開箱即用的 web 和 api 兩個中間件組以包含能夠應用到 Web UI 和 API 路由的通用中間件:

/**
* 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',
'bindings',
],
'Test'=>[
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\Test::class,
]
];
中間件組能夠被分配給路由和控制器動做,使用和單箇中間件分配一樣的語法。再次申明,中間件組的目的只是讓一次分配給路由多箇中間件的實現更加簡單

Route::group(['middleware' => ['Test']], function() {
Route::get('/', 'IndexController@index');
Route::any('test','IndexController@test');
});
可終止的中間件
有時候中間件可能須要在 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 方法將會接收請求和響應做爲參數。一旦你定義了一個可終止的中間件,應該將其加入到 HTTP kernel 的全局中間件列表中。

當調用中間件上的 terminate 方法時,Laravel 將會從服務容器中取出該中間件的新的實例,若是你想要在調用 handle 和 terminate 方法時使用同一個中間件實例,則須要使用容器的 singleton 方法將該中間件註冊到容器中。

laravel框架中構造方法中調用sessionpublic function __construct(){ $this->middleware(function ($request, $next) { $user_data = $request->session() -> get('user_data'); if(empty($user_data)) { redirect('/login')->send(); } return $next($request); }); }

相關文章
相關標籤/搜索