{{TOC}} {{DOCVER 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11}} == Введение == Посредники (англ. //middleware//) предоставляют удобный механизм для фильтрации HTTP-запросов вашего приложения. Например, в Laravel есть посредник для проверки аутентификации пользователя. Если пользователь не аутентифицирован, посредник перенаправит его на экран входа в систему. Если же пользователь аутентифицирован, посредник позволит запросу пройти далее в приложение. Конечно, посредники нужны не только для авторизации. ((ВП:CORS))-посредник может пригодиться для добавления особых заголовков ко всем ответам в вашем приложении. А посредник логов может зарегистрировать все входящие запросы. В Laravel есть несколько стандартных посредников, включая посредники для аутентификации и ((ВП:CSRF))-защиты. Все они расположены в каталоге %%(t)app/Http/Middleware%%. == Создание посредника == Чтобы создать посредника, используйте команду Artisan %%(sh)make:middleware%%: %%(sh) php artisan make:middleware CheckAge %% Эта команда поместит новый класс %%(t)CheckAge%% в ваш каталог %%(t)app/Http/Middleware%%. В этом посреднике мы будем пропускать только те запросы, в которых %%(t)age%% будет больше 200, а во всех остальных случаях будем перенаправлять пользователей на "home" URI. %% age <= 200) { return redirect('home'); } return $next($request); } } %% Как видите, если переданный %%(t)age%% меньше или равен %%(t)200%%, то посредник вернёт клиенту переадресацию, иначе, запрос будет передан далее в приложение. Чтобы передать запрос дальше в приложение (позволяя посреднику "передать" его), просто вызовите замыкание %%$next%% с параметром %%$request%%. Проще всего представить посредника как набор "уровней", которые должен пройти HTTP-запрос, прежде чем он дойдёт до вашего приложения. Каждый уровень может проверить запрос и даже вовсе отклонить его. === Выполнение посредника "до" или "после" запроса === Момент, в который сработает посредник - до или после запроса, зависит от него самого. Например, этот посредник выполнит некоторую задачу **прежде**, чем запрос будет обработан приложением: %% \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, //для версии 5.2 и выше: 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, //для версии 5.3 и выше: 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, //для версии 5.2 и ранее: 'auth' => \App\Http\Middleware\Authenticate::class, ]; %% %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51) Когда посредник определён в HTTP-ядре, вы можете использовать метод %%(t)middleware%% для назначения посредника на маршрут: ~%% Route::get('admin/profile', function () { // })->middleware('auth'); ~%% Для назначения нескольких посредников для маршрута: ~%% Route::get('/', function () { // })->middleware('first', 'second'); ~%% %% %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) Когда посредник определён в HTTP-ядре, вы можете использовать ключ %%(t)middleware%% в массиве параметров маршрута: ~%% Route::get('admin/profile', ['middleware' => 'auth', function () { // }]); ~%% Используйте массив для назначения нескольких посредников для маршрута: ~%% Route::get('/', ['middleware' => ['first', 'second'], function () { // }]); ~%% Вместо использования массива вы можете использовать сцепку метода %%middleware()%% с определением маршрута: ~%% Route::get('/', function () { // })->middleware(['first', 'second']); ~%% %% При назначении посредника вы можете указать полное имя класса: %% use App\Http\Middleware\CheckAge; Route::get('admin/profile', function () { // })->middleware(CheckAge::class); %% %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15) === Группы посредников === Иногда бывает полезно объединить несколько посредников под одним ключом, чтобы проще назначать их на маршруты. Это можно сделать при помощи свойства %%$middlewareGroups%% вашего HTTP-ядра. Изначально в Laravel есть группы посредников %%(t)web%% и %%(t)api%%, которые содержат те посредники, которые часто применяются к вашим маршрутам веб-UI и API: ~%% /** * Группы посредников маршрутов приложения. * * @var array */ 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:60,1', 'auth:api', ], ]; ~%% Группы посредников могут быть назначены на маршруты и действия контроллера с помощью того же синтаксиса, что и для одного посредника. Группы посредников просто делают проще единое назначение нескольких посредников на маршрут: ~%% Route::get('/', function () { // })->middleware('web'); Route::group(['middleware' => ['web']], function () { // }); ~%% .(alert) Группа посредников %%(t)web%% автоматически применяется к вашему файлу %%(t)routes/web.php%% сервис-провайдером %%(t)RouteServiceProvider%%. %% == Параметры посредника == В посредник можно передавать дополнительные параметры. Например, если в вашем приложении необходима проверка того, есть ли у аутентифицированного пользователя определённая "роль" для выполнения данного действия, вы можете создать посредника %%(t)CheckRole%%, который принимает название роли в качестве дополнительного аргумента. Дополнительные параметры посредника будут передаваться в посредник после аргумента %%$next%%: %% user()->hasRole($role)) { // Redirect... } return $next($request); } } %% Параметры посредника можно указать при определении маршрута, отделив название посредника от параметров двоеточием %%(t):%%. Сами параметры разделяются запятыми: %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51) ~%% Route::put('post/{id}', function ($id) { // })->middleware('role:editor'); ~%% %% %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) ~%% Route::put('post/{id}', ['middleware' => 'role:editor', function ($id) { // }]); ~%% %% == Посредник terminable == Иногда посредник должен выполнить некоторые действия уже после отправки HTTP-отклика браузеру. Например, посредник "session", поставляемый с Laravel, записывает данные сессии в хранилище после отправки ответа в браузер. Если вы определите метод %%terminate()%% в посреднике, то он будет автоматически вызываться после отправки отклика в браузер: %%