Articles

Laravel middleware how it works

Laravel middleware is an intermediate application layer that intervenes between the user's request and the application's response.

This means that when the user (Laravel view) makes a request to the server (Laravel controller), the request will go through the middleware. This way the middleware can check if the request is authenticated or not: 

  • if the user's request is authenticated, the request is sent to the backend;
  • if the user's request is unauthenticated, the middleware will redirect the user to the login screen.

Laravel allows you to defifinish and use additional middleware to perform a variety of tasks except authentication. 

Laravel middlewares, such as authentication and CSRF protection, are located in the directory app/Http/Middleware .

We can therefore say that the middleware is an http request filter, through which it is possible to verify conditions and perform actions.

Creating middleware

To create a new middleware we run the following command:

php artisan make:middleware <name-of-middleware>

We create the middleware and we call it CheckAge, artisan will answer us as follows:

The window above shows that the middleware has been successfully created with the name ” CheckAge ".

To see if the CheckAge middleware is created or not, go to the project in the app/Http/Middleware folder, and you will see the newly created file

The newly created file has the following code

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

Use middleware

To use middleware, we need to register it.

There are two types of middleware in Laravel:

  • Middleware globale
  • Route Middleware

Il global middleware will be executed on every HTTP request from the application, while the Route Middleware will be assigned to a specific path. Middleware can be registered at app/Http/Kernel.php. This file contains two properties $middleware e $routeMiddleware . The $middleware property is used to register global middleware and ownership $routeMiddleware is used to register route-specific middleware.

To register global middleware, list the class at the end of the $middleware property.

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

To register route-specific middleware, add the key and value to the $routeMiddleware property.

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,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];

We created CheckAge in the previous example. We can now register this in the middleware route property. The code for such a registration is shown below.

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,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'Age' => \App\Http\Middleware\CheckAge::class,
    ];

Middleware parameters

We can also pass parameters with Middleware. 

For example, if your application has different roles like user, admin, super admin etc. and you want to authenticate the action based on the role, you can do it by passing the parameters with the middleware. 

The middleware we created contains the following function, and we can pass custom arguments after the argument $next .

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

Now let's try to set the role parameter to a new middleware that we are going to create from scratch, then proceed to create Role Middleware by running the following command

Modify the handle method as follows

<?php

namespace App\Http\Middleware;
use Closure;

class RoleMiddleware {
   public function handle($request, Closure $next, $role) {
      echo "Role: ".$role;
      return $next($request);
   }
}

we added the parameter $role, and inside the method the line echo to write the output the name of the role.

Innovation newsletter
Don't miss the most important news on innovation. Sign up to receive them by email.

Now let's register the RoleMiddleware middleware for a specific path

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,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'Age' => \App\Http\Middleware\CheckAge::class,
        'Role' => \App\Http\Middleware\RoleMiddleware::class,
    ];

Now to test the middleware with the parameter, we need to create a request and a response. To simulate the response let's create the controller that we will call TestController

php artisan make:controller TestController --plain

the command just executed will create a new controller inside the folder app/Http/TestController.php, and change the method index with the line echo "<br>Test Controller.";

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;

class TestController extends Controller {
   public function index() {
      echo "<br>Test Controller.";
   }
}

After setting up the response, we build the request by editing the file routes.phpby adding the route role

Route::get('role',[
   'middleware' => 'Role:editor',
   'uses' => 'TestController@index',
]);

at this point we can try the example by visiting the URL http://localhost:8000/role

and in the browser we will see the two echo

Role editor
Test Controller

Terminable Middleware

Il terminable Middleware performs some tasks after the response is sent to the browser. This can be achieved by creating a middleware with the method terminate in the middleware. Il terminable Middleware must be registered with the middleware global. The method terminate will receive two arguments $request e $response. 

The method Terminate must be created as shown in the following code.

php artisan make:middleware TerminateMiddleware

Once the middleware is created app/Http/Middleware/TerminateMiddleware.php let's modify the code as follows

<?php

namespace App\Http\Middleware;
use Closure;

class TerminateMiddleware {
   public function handle($request, Closure $next) {
      echo "Executing statements of handle method of TerminateMiddleware.";
      return $next($request);
   }
   
   public function terminate($request, $response) {
      echo "<br>Executing statements of terminate method of TerminateMiddleware.";
   }
}

in this case we have a method handle and a method terminate with the two parameters $request e $response.

Now let's register the Middleware

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,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'Age' => \App\Http\Middleware\CheckAge::class,
        'Role' => \App\Http\Middleware\RoleMiddleware::class,
        'terminate' => \App\Http\Middleware\TerminateMiddleware::class,
    ];

Now we need to create the controller to simulate the response

php artisan make:controller XYZController --plain

modifying the contents of the class

class XYZController extends Controller {
   public function index() {
      echo "<br>XYZ Controller.";
   }
}

Now we need to edit the file routes/web.php adding the routes needed to activate the request

Route::get('terminate',[
   'middleware' => 'terminate',
   'uses' => 'XYZController@index',
]);

at this point we can try the example by visiting the URL http://localhost:8000/terminate

and in the browser we will see the following lines

Executing statements of handle method of TerminateMiddleware
XYZController
Executing statements of terminate method of TerminateMiddleware

Ercole Palmeri

You may also be interested in:

Innovation newsletter
Don't miss the most important news on innovation. Sign up to receive them by email.

Latest Articles

The Benefits of Coloring Pages for Children - a world of magic for all ages

Developing fine motor skills through coloring prepares children for more complex skills like writing. To color…

May 2, 2024

The Future is Here: How the Shipping Industry is Revolutionizing the Global Economy

The naval sector is a true global economic power, which has navigated towards a 150 billion market...

May 1, 2024

Publishers and OpenAI sign agreements to regulate the flow of information processed by Artificial Intelligence

Last Monday, the Financial Times announced a deal with OpenAI. FT licenses its world-class journalism…

April 30 2024

Online Payments: Here's How Streaming Services Make You Pay Forever

Millions of people pay for streaming services, paying monthly subscription fees. It is common opinion that you…

April 29 2024