Версія фреймворка: 8.x

Middleware

Вступ

Middleware забезпечує зручний механізм фільтрації HTTP-запитів, що надходять у вашу програму. Наприклад, Laravel включає Middlware, яке підтверджує автентичність користувача вашого додатка. Якщо користувач не аутентифікований, Middlware перенаправить користувача на екран входу. Однак, якщо користувача аутентифіковано, Middlware дозволить запиту перейти далі до програми.

Можна створити додаткове Middlware для виконання різноманітних завдань, крім автентифікації. Middleware CORS може бути відповідальним за додавання відповідних заголовків до всіх відповідей, що залишають вашу програму. Middleware для реєстрації може реєструвати всі вхідні запити до вашої програми.

У фреймворк Laravel входить кілька проміжних програм, включаючи Middlware для автентифікації та захисту CSRF. Всі ці проміжні програми знаходяться вapp/Http/Middlewareкаталог.

Визначення проміжного програмного забезпечення

Щоб створити нове Middlware, використовуйтеmake:middlewareКоманда ремісників:

php artisan make:middleware CheckAge

Ця команда розмістить новуCheckAgeклас у вашомуapp/Http/Middlewareкаталог. У цьому проміжному програмному забезпеченні ми дозволимо доступ до маршруту лише за умови, що наданоageбільше 200. В іншому випадку ми перенаправляємо користувачів назад наhomeНенависть:

<?php

namespace App\Http\Middleware;

use Closure;

class CheckAge
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->age <= 200) {
            return redirect('home');
        }

        return $next($request);
    }
}

Як бачите, якщо данеageменше або дорівнює200, Middlware поверне клієнту перенаправлення HTTP; в іншому випадку запит буде передано далі в заявку. Щоб передати запит глибше в програму (дозволивши Middlware "пройти"), зателефонуйте на$nextзворотний дзвінок за допомогою$request.

Краще уявити Middlware, оскільки низка "шарів" HTTP-запитів повинна пройти, перш ніж вони потраплять у вашу програму. Кожен шар може розглянути запит і навіть повністю відхилити його.

Усі проміжні програми вирішуються черезслужбовий контейнер, тож ви можете навести натяк на будь-які залежності, які вам потрібні в конструкторі проміжного програмного забезпечення.

До та після проміжного програмного забезпечення

Запуск проміжного програмного забезпечення до або після запиту залежить від самого проміжного програмного забезпечення. Наприклад, наступне Middlware виконує певне завданняранішезапит обробляється додатком:

<?php

namespace App\Http\Middleware;

use Closure;

class BeforeMiddleware
{
    public function handle($request, Closure $next)
    {
        // Perform action

        return $next($request);
    }
}

Однак це Middlware виконало б своє завданняпіслязапит обробляється додатком:

<?php

namespace App\Http\Middleware;

use Closure;

class AfterMiddleware
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        // Perform action

        return $response;
    }
}

Реєстрація проміжного програмного забезпечення

Глобальне ПЗ

Якщо ви хочете, щоб Middlware працювало під час кожного запиту HTTP до вашої програми, перелічіть клас проміжного програмного забезпечення в$middlewareвласність вашогоapp/Http/Kernel.phpклас.

Призначення проміжного програмного забезпечення маршрутам

Якщо ви хочете призначити Middlware для певних маршрутів, спочатку слід призначити Middlware ключем у вашомуapp/Http/Kernel.phpфайл. За замовчуванням$routeMiddlewareвластивість цього класу містить записи проміжного програмного забезпечення, що входить до складу Laravel. Щоб додати свій власний, додайте його до цього списку та призначте йому вибраний вами ключ:

// Within App\Http\Kernel Class...

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,
];

Після того, як Middlware буде визначено в ядрі HTTP, ви можете використовуватиmiddlewareметод призначення маршрутного проміжного програмного забезпечення:

Route::get('admin/profile', function () {
    //
})->middleware('auth');

Ви також можете призначити маршруту кілька проміжних програм:

Route::get('/', function () {
    //
})->middleware('first', 'second');

Призначаючи Middlware, ви також можете передати повну назву класу:

use App\Http\Middleware\CheckAge;

Route::get('admin/profile', function () {
    //
})->middleware(CheckAge::class);

Призначаючи Middlware групі маршрутів, іноді може знадобитися запобігти застосуванню проміжного програмного забезпечення до окремого маршруту в групі. Ви можете досягти цього за допомогоюwithoutMiddlewareметод:

use App\Http\Middleware\CheckAge;

Route::middleware([CheckAge::class])->group(function () {
    Route::get('/', function () {
        //
    });

    Route::get('admin/profile', function () {
        //
    })->withoutMiddleware([CheckAge::class]);
});

withoutMiddlewareметод може видалити лише Middlware маршруту і не застосовується доглобальне Middlware.

Групи проміжного програмного забезпечення

Іноді вам може знадобитися згрупувати кілька проміжних програм за допомогою однієї клавіші, щоб полегшити їх призначення для маршрутів. Ви можете зробити це за допомогою$middlewareGroupsвластивість вашого ядра HTTP.

Нестандартно приходить Laravelwebіapiгрупи проміжного програмного забезпечення, що містять загальне Middlware, яке ви можете застосувати до свого веб-інтерфейсу та маршрутів 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:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

Групи проміжного програмного забезпечення можуть бути призначені для маршрутів та дій контролера, використовуючи той самий синтаксис, що і окремі проміжні програми. Знову ж таки, проміжні групи роблять зручнішим призначати багато проміжних програм до маршруту одночасно:

Route::get('/', function () {
    //
})->middleware('web');

Route::group(['middleware' => ['web']], function () {
    //
});

Route::middleware(['web', 'subscribed'])->group(function () {
    //
});
Нестандартно,webгрупа проміжного програмного забезпечення автоматично застосовується до вашогоroutes/web.phpфайлRouteServiceProvider.

Сортування проміжного програмного забезпечення

Рідко вам може знадобитися Middlware для виконання в певному порядку, але не мати контролю над своїм замовленням, коли вони призначені маршруту. У цьому випадку ви можете вказати пріоритет проміжного програмного забезпечення за допомогою$middlewarePriorityвласність вашогоapp/Http/Kernel.phpфайл:

/**
 * The priority-sorted list of middleware.
 *
 * This forces non-global middleware to always be in the given order.
 *
 * @var array
 */
protected $middlewarePriority = [
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
    \Illuminate\Routing\Middleware\ThrottleRequests::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];

Параметри проміжного програмного забезпечення

Middleware також може отримувати додаткові параметри. Наприклад, якщо вашій програмі потрібно виконати перевірку, що автентифікований користувач має задану "роль" перед виконанням певної дії, ви можете створитиCheckRoleMiddlware, яке отримує ім'я ролі як додатковий аргумент.

Додаткові параметри проміжного програмного забезпечення будуть передані проміжному програмному забезпеченню після$nextаргумент:

<?php

namespace App\Http\Middleware;

use Closure;

class CheckRole
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string  $role
     * @return mixed
     */
    public function handle($request, Closure $next, $role)
    {
        if (! $request->user()->hasRole($role)) {
            // Redirect...
        }

        return $next($request);
    }

}

Параметри проміжного програмного забезпечення можуть бути вказані при визначенні маршруту, відокремлюючи ім'я та параметри проміжного програмного забезпечення за допомогою a:. Кілька параметрів слід розділяти комами:

Route::put('post/{id}', function ($id) {
    //
})->middleware('role:editor');

Можливе Middlware

Іноді Middlware, можливо, доведеться виконати якусь роботу після того, як відповідь HTTP надіслано браузеру. Якщо ви визначитеterminateна проміжному програмному забезпеченні, а веб-сервер використовує FastCGI,terminateметод буде автоматично викликаний після того, як відповідь буде надіслана браузеру:

<?php

namespace Illuminate\Session\Middleware;

use Closure;

class StartSession
{
    public function handle($request, Closure $next)
    {
        return $next($request);
    }

    public function terminate($request, $response)
    {
        // Store the session data...
    }
}

terminateметод повинен отримувати як запит, так і відповідь. Після того, як ви визначили Middlware, яке можна термінувати, вам слід додати його до списку маршрутних або глобальних проміжних програм уapp/Http/Kernel.phpфайл.

При дзвінку вterminateдля вашого проміжного програмного забезпечення, Laravel вирішить новий екземпляр проміжного програмного забезпечення зслужбовий контейнер. Якщо ви хочете використовувати той самий екземпляр проміжного програмного забезпечення, коли файлhandleіterminateвикликаються методи, зареєструйте Middlware з контейнером, використовуючи контейнериsingletonметод. Зазвичай це слід робити вregisterметод вашогоAppServiceProvider.php:

use App\Http\Middleware\TerminableMiddleware;

/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
    $this->app->singleton(TerminableMiddleware::class);
}