PHP Laravel - Middleware 應用與介紹 - 筆記長也NotesHazuya

PHP Laravel - Middleware 應用與介紹

2020-06-08 00:24:25   Laravel

Middleware

HTTP 中間件提供了驗證過濾的機制,在請求進入 route 之前,可以先驗證使用者身份或是其他任務,成功後才進入 route。而如果沒有中間件,就必須在每一個 route 重複篩寫程式碼進行驗證工作。 在 laravel 中,所有的中間件都被放在 app/Http/Middleware 目錄之下。

建立 Middleware

php artisan make:middleware userAuth

利用這個指令建立中間件,可以在 app/Http/Middleware 看到一個名為 userAuth.php 的檔案。

Middleware 執行時機

中間件可以在 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 介紹的文章當中已經介紹過,如果要讓多個路由都經過同一個中間件,可以使用這個方法。

文章至此告一段落,下一篇將會總結至本篇的所有部分,應當可以設計出一個基本的登入系統。


長也

我只專注做好自己能做的事情,別人要做什麼我無法干涉。