What is Middleware

When you ask what is middleware in laravel, I want you to imagine guard standing at the entrance of a compound that inspects whoever enters and leaves the compound. No one can enter into the compound except through the get. And the guard can make any kinds of checkups on him and as the result he has full right to let him enter or return him back. This what middleware means. Middleware is a series of layers HTTP requests must pass through before they hit your application. Just like the guard, every layer can examine the request and even reject it like the guard. For example , there is a middleware that authenticates user. If the user is not authenticated, the middleware redirects him/her to the login page. It’s main objective is to filter any unwanted actions that pass through our application.

Middleware is a mechanism that filters any http requests entering your application. It also used to handle different things inside laravel application. Things like Authentication, Session,cookies, CSRF protection, Roles , logging all incoming requests and more. Also, there is a CORS middleware that is responsible for adding the proper headers to all responses leaving your application. After saying this lets see how to define middleware.

Defining Middleware

You can create middleware by executing the following command

php artisan make:middleware <middleware_name>

Replace <middleware_name> with your own name. After executing the command you will see a file created at app/Http/Middleware directory.

For Example, run the following command

php artisan make:middleware CheckAge

Running this command will create a new file namedĀ CheckAge insideĀ app/Http/Middleware directory. And its content will looks like the following:

<?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)
    {
        return $next($request);
    }
}

Middlewares must be registered before use. Next we will see how to register a middleware.

Registering Middlewares

Registration of middleware takes place in Kernel.php file which is located at app/Http. Inside this file you will find two properties $middleware and $routeMiddleware. These two properties are used to register the two types of middlewares in laravel. These two types of middlewares are:

  • Global Middleware
  • Route Middleware
Global Middleware

This type of middleware runs on every single http request of the application. The global middleware belongs to the $middleware property of the Kernel.php class. If you want to register a global middleware, You can list your middleware class in $middleware property of your app/Http/Kernel.php like the following:

    protected $middleware = [
        \App\Http\Middleware\CheckAge::class,
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

Route Middlewares

This type of middleware is used to register a middleware to one specific route. For the route middlewares use the $routeMiddleware property of the Kernel.php class. You can register route middlewares like the following:

 protected $routeMiddleware = [
     'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
     'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
     'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
     'can' => \Illuminate\Auth\Middleware\Authorize::class,
     'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
     'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
     'checkAge' => \App\Http\Middleware\CheckAge::class,
 ];
How To Assign Middleware to Route

Once you have defined the middleware in the Kernel.php class, use the middleware method to assign middleware to a route like the following:

Route::get('home/secret', function () {
   return view('secret');
})->middleware('checkAge');

If you want to assign multiple middlewares on one route, just pass the middleware name as second,third,.. parameter on middleware function:

->middleware('checkAge', 'auth');

Middleware Groups

What if you have lots of middlewares to be assigned on one route? Rather than assigning each and every middlewares individually, you can group them under a single key and assign just this single key. That’s interesting!

In order to succeed this, you can use the property $middlewareGroups which is found inside kernel.php. Here is what it looks like:

    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:60,1',
            'bindings',
        ],
    ];

Just you can list your middlewares under ‘web’ if your aim is for web or under ‘api’ for API. Then assign your middleware in to route like we did above.

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

Middleware Parameters

You can also pass parameters to middlewares. You will need to pass parameter to middlewares in different situations. For example, Lets say you have different roles on your application and different dashboard for each of roles you have. Then, You are required to pass role with the middleware. In these and other situations you need a parameterized middleware.

For Example,

<?php

namespace App\Http\Middleware;

use Closure;

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

        return $next($request);
    }

}

While assigning this middleware to routes you can specify the parameter as follows

Route::get('open/{role}', function ($role) {
    //
})->middleware('OpenDashboard:role');

Here the parameter is the text next to the middleware separated by ‘:’ (colon).

Terminable Middleware

In simple words These kinds of middlewares are used to perform some work after the response has been sent to the browser. It may like storing sessions, or other operations. To make your middleware terminable middleware simply add terminate() method right after the handle method.

<?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)
    {
        return $next($request);
    }
    public function terminate($request, $response)
    {
        //write you code
    }
}

This means, the terminate method will be called automatically after the response is sent to the browser.

Finally, The interesting part of middleware is its flexibility. There is an option that allows you run the middleware whether before request or after the request is made by changing some block of code. Here is the trick:

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

The above middleware executes before the request is made. Now lets see the middleware that executes after the request is handled by the application.

public function handle($request, Closure $next)
    {
        $response = $next($request);
        return $response;
    }

As you see above the whole trick lies on this $response = $next($request); line of code. The middleware returns the response of the executed request.


That’s all about Middlewares

Reference: Laravel official documentation


0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *