middleware


Register middleware

  • Global middleware
  • Assign middleware to routes
  • Middleware group
    • Sort of middleware
    • Middleware Parameters
    • Terminable Middleware
  • Introduction

    Middleware provides a convenient mechanism to filter HTTP requests entering an application. For example, Laravel includes a middleware that verifies user authentication for your application. If the user is not authenticated, the middleware will redirect the user to the login interface. However, if the user is authenticated, the middleware will further allow the request to the application.

    Of course, in addition to identity authentication, you can also write additional middleware to perform various tasks. For example: CORS middleware can be responsible for adding appropriate header information to all responses leaving the application; logging middleware can log all requests coming into the application.

    Laravel comes with some middleware, including authentication, CSRF protection, etc. All these middlewares are located in the app/Http/Middleware directory.

    Define middleware

    Create new ones by running the make:middleware Artisan command Middleware:

    php artisan make:middleware CheckAge

    This command will create a new CheckAge class in the app/Http/Middleware directory. In this middleware, we only allowage Requests with parameters greater than 200 will access this route, otherwise, they will be redirected to 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); 
             }
          }

    As you can see, if If the specified age parameter is less than or equal to 200, this middleware will return an HTTP redirect to the client; otherwise, the request will be passed further to the application. To have the request continue to be passed to the application (i.e. allow the middleware to "pass" validation), just call the callback function $next with $request as the parameter.

    It's best to think of middleware as a series of HTTP requests that must be passed through to get to the "layer" of your application. Each layer checks the request to see if it meets certain criteria, and can even reject it entirely (before requesting access to your application) if it doesn't.

    {Tip} All middleware is passed through the service container, so you can type any dependencies you need in the constructor of your middleware.

    Pre & post middleware

    Middleware is executed before or after the request, depending on the middleware itself. For example, the following middleware will perform some task before the application handles the request:

    <?php
      namespace App\Http\Middleware;
      use Closure;class BeforeMiddleware{  
        public function handle($request, Closure $next) 
           {    
               // Perform action   
               return $next($request); 
             }
         }

    However, this middleware performs some task after the application requests

    <?php
       namespace App\Http\Middleware;
       use Closure;
       class AfterMiddleware{ 
          public function handle($request, Closure $next) 
             {    
                 $response = $next($request); 
                 // Perform action        
                 return $response;   
               }
          }

    Registration middleware

    Global middleware

    If you want the middleware to run during every HTTP request your application handles. Just list this middleware in the $middleware attribute in app/Http/Kernel.php

    ###

    Distribute middleware for routing

    Assuming that you want to distribute middleware for a specified route, you should first allocate a middleware for the middleware in the app/Http/Kernel.php file. key. By default, Laravel's built-in middleware is included under the $routeMiddleware attribute in this class. To add a custom middleware, just append it to the list and assign it a custom key. For example:

    // 在 App\Http\Kernel 类中...
    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,
     ];

    Once the middleware is defined in the HTTP kernel, you can assign middleware to the route through the middleware method:

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

    You can also assign middleware to the route Distributing multiple middleware:

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

    When assigning middleware, you can also pass the full class name:

    use App\Http\Middleware\CheckAge;
    Route::get('admin/profile', function () { 
       //
    })->middleware(CheckAge::class);

    Middle Component

    Sometimes you may want to use a key to package multiple middleware into a group so that they can be easily applied to routes. You can use the $middlewareGroups attribute of Http Core.

    Laravel has built-in web and api middleware groups out of the box, which contain common middleware you may want to apply to Web UI and API routing:

    /**
     * 应用程序的路由中间件组
     *
     * @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',],
        ];

    Middleware groups can be assigned to route and controller actions using the same syntax as individual middleware. Likewise, middleware makes it easier to assign multiple middlewares to a route at once:

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

    {Tip} RouteServiceProvider defaults to the web middleware group Automatically applied to routes/web.php.

    Sorting Middleware

    Rarely, you may need middleware to They are executed in a specific order, but you have no control over their order when they are assigned to routes. In this case, the middleware priority can be specified using the $middlewarePriority attribute of the app/Http/Kernel.php file:

    /**
     * 中间件的优先级排序列表
     *
     * 将会强制非全局中间件始终保持给定的顺序。
     *
     * @var array
     */
     protected $middlewarePriority = [
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\Authenticate::class,
        \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \Illuminate\Auth\Middleware\Authorize::class,];

    Middleware parameters

    Middleware can also receive other parameters. For example, if your application needs to verify that the user is a given "role" before performing a given action, you can create a CheckRole middleware that receives the "role" name as an additional parameter .

    Additional intermediate parameters should be passed to the middleware after the $next parameter:

    <?php
      namespace App\Http\Middleware;
      use Closure;class CheckRole{  
        /**
         * 处理传入的参数
         *
         * @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);  
            }
          }

    Separate the middle by a : when defining the route Use the file name and parameters to specify middleware parameters. Use commas to separate multiple parameters:

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

    Terminable Middleware

    Sometimes, middleware may need to do some work after preparing the HTTP response. For example, Laravel's built-in "session" middleware writes session data to storage when the response is fully ready. If you define a terminate method on your middleware, it will be called automatically after the response is ready to be sent to the browser.

    <?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 The method should receive both the request and the response. After defining this middleware, don't forget to add it to the route list or the global middleware of the app/Http/Kernel.php file.

    When you call the terminate method on middleware, Laravel will resolve a new middleware instance from the service container. If you are using the same middleware instance while calling the handle and terminate methods, use the container's singleton method to register the middleware in the container.

    This article was first published on the LearnKu.com website.