пользователей: 30398
предметов: 12406
вопросов: 234839
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ

Вспомогательное программное обеспечение. Middleware.

HTTP-посредники (англ. middleware) предоставляют удобный механизм для фильтрации HTTP-запросов вашего приложения. Например, в Laravel есть посредник для проверки аутентификации пользователя. Если пользователь не аутентифицирован, посредник перенаправит его на экран входа в систему. Если же пользователь аутентифицирован, посредник позволит запросу пройти далее в приложение.

Конечно, посредники нужны не только для авторизации. CORS-посредник может пригодиться для добавления особых заголовков ко всем ответам в вашем приложении. А посредник логов может зарегистрировать все входящие запросы.

В Laravel есть несколько стандартных посредников, включая посредники для обслуживания, аутентификации, CSRF-защиты и многие другие. Все они расположены в каталоге app/Http/Middleware.

Создание посредника

Чтобы создать посредника, используйте команду Artisan make:middleware:

+ 5.2

добавлено в 5.2 (08.12.2016)

php artisan make:middleware AgeMiddleware

+ 5.1 5.0

добавлено в 5.1 (19.06.2016) 5.0 (08.02.2016)

php artisan make:middleware OldMiddleware

Эта команда поместит новый класс AgeMiddleware (для версии 5.1 и ранее OldMiddleware) в ваш каталог app/Http/Middleware. В этом посреднике мы будем пропускать только те запросы, в которых age будет больше 200, а во всех остальных случаях будем перенаправлять пользователей на «home» URI.

<?php



namespace App\Http\Middleware;



use Closure;



class AgeMiddleware

// для версии 5.1 и ранее

// class OldMiddleware

{

  /**

   * Выполнение фильтра запроса.

   *

   * @param  \Illuminate\Http\Request  $request

   * @param  \Closure  $next

   * @return mixed

   */

  public function handle($request, Closure $next)

  {

    if ($request->input('age') <= 200) {

      return redirect('home');

    }



    return $next($request);

  }



}

Как видите, если переданный age меньше или равен 200, то посредник вернёт клиенту переадресацию, иначе, запрос будет передан далее в приложение. Чтобы передать запрос дальше в приложение (позволяя посреднику «передать» его), просто вызовите замыкание $next с параметром $request.

Проще всего представить посредника как набор «уровней», которые должен пройти HTTP-запрос, прежде чем он дойдёт до вашего приложения. Каждый уровень может проверить запрос и даже вовсе отклонить его.

Посредник «до» и «после»

Момент, в который сработает посредник — до или после запроса, зависит от него самого. Например, этот посредник выполнит некоторую задачу прежде, чем запрос будет обработан приложением:

<?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;

  }

}

Регистрация посредника

Глобальный посредник

Если вы хотите, чтобы посредник запускался для каждого HTTP-запроса в вашем приложении, добавьте этот посредник в свойство $middleware класса app/Http/Kernel.php.

Назначение посредника для маршрутов

Если вы хотите назначить посредника для конкретных маршрутов, то сначала вам надо добавить сокращённый ключ посредника в класс app/Http/Kernel.php. По умолчанию свойство $routeMiddleware этого класса содержит записи посредников Laravel. Чтобы добавить ваш собственный посредник, просто добавьте его к этому списку и присвойте ему ключ на свой выбор. Например:

// в классе App\Http\Kernel...



protected $routeMiddleware = [

  'auth' => \App\Http\Middleware\Authenticate::class,

  'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,

  'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,

  //для версии 5.2 и выше:

  'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,

];

Когда посредник определён в HTTP-ядре, вы можете использовать ключ middleware в массиве параметров маршрута:

Route::get('admin/profile', ['middleware' => 'auth', function () {

  //

}]);

Используйте массив для назначения нескольких посредников для маршрута:

Route::get('/', ['middleware' => ['first', 'second'], function () {

  //

}]);

Вместо использования массива вы можете использовать сцепку метода middleware() с определением маршрута:

Route::get('/', function () {

  //

})->middleware(['first', 'second']);

+ 5.2

добавлено в 5.2 (08.12.2016)

При назначении посредника вы можете также передать полное имя класса:

use App\Http\Middleware\FooMiddleware;



Route::get('admin/profile', ['middleware' => FooMiddleware::class, function () {

  //

}]);

Группы посредников

Иногда бывает полезно объединить несколько посредников под одним ключом, чтобы проще назначать их на маршруты. Это можно сделать при помощи свойства $middlewareGroups вашего HTTP-ядра.

Из коробки в Laravel есть группы посредников web и 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,

  ],



  'api' => [

    'throttle:60,1',

    'auth:api',

  ],

];

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

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

  //

});

Не забывайте, группа посредников web автоматически применяется к вашему стандартному файлу routes.php сервис-провайдером RouteServiceProvider.

Параметры посредника

В посредник можно передавать свои дополнительные параметры. Например, если в вашем приложении необходима проверка того, есть ли у аутентифицированного пользователя определённая «роль» для выполнения данного действия, вы можете создать посредника RoleMiddleware, который принимает название роли в качестве дополнительного аргумента.

Дополнительные параметры посредника будут передаваться в посредник после аргумента $next:

<?php



namespace App\Http\Middleware;



use Closure;



class RoleMiddleware

{

  /**

   * Выполнение фильтрации запроса.

   *

   * @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);

  }



}

Параметры посредника можно указать при определении маршрута, отделив название посредника от параметров двоеточием :. Сами параметры разделяются запятыми:

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

  //

}]);

Посредник terminable

Иногда посредник должен выполнить некоторые действия уже после отправки HTTP-ответа браузеру. Например, посредник «session», поставляемый с Laravel, записывает данные сессии в хранилище после отправки ответа в браузер. Для этого нужно определить посредника как «terminable», добавив в него метод terminate():

<?php



namespace Illuminate\Session\Middleware;



use Closure;



class StartSession

{

  public function handle($request, Closure $next)

  {

    return $next($request);

  }



  public function terminate($request, $response)

  {

    // Сохранение данных сессии...

  }



}

Метод terminate() получает и запрос, и ответ. Определив посредника как «terminable», вы должны добавить его в список глобальных посредников в вашем HTTP-ядре.

При вызове метода terminate() в посреднике, Laravel получит свежий экземпляр посредника из сервис-контейнера. Если вы хотите использовать тот же самый экземпляр посредника при вызовах методов handle() и terminate(), зарегистрируйте посредника в контейнере при помощи метода singleton().

 


22.06.2017; 17:38
хиты: 104
рейтинг:0
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2024. All Rights Reserved. помощь