w3resource

Laravel (5.7) Middleware

Introduction

Middleware provides a convenient mechanism for filtering HTTP requests entering your application. For example, Laravel includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to the login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.

Creating Middleware

Thanks to the artisan, creating middlewares in Laravel is easy. All we need do is open a terminal in the project root and run the following command.

// Replace <MiddlewareName> with the actual name of the middleware.
php artisan make:middleware <MiddlewareName>

This command creates our middleware class in app/Http/Middleware. To create our own middleware (which we will call DoingSomething, we can.

php artisan make:middleware DoingSomething

So we can now open our middleware class and add our logic to the middleware. Remember, our middleware handles site maintenance mode. We need to first import the HttpException first. At the top of the file, we can do this use Symfony\Component\HttpKernel\Exception\HttpException; In the handle method of our middleware, we can just do this.

public function handle($request, Closure $next)
{
    throw new HttpException(503);
}

By throwing this exception, Laravel knows to load the 503.blade.php file. This should contain the message for maintenance mode.

Registering a Middleware

Now that we've created a middleware, we need to let the application know the middleware exists. If you want a middleware to run on every request, go to app/Http/kernel.php and add the middleware FQN to Kernel class $middleware property.

protected $middleware = [
    ...
    \App\Http\Middleware\DoingSomething::class
];

By doing this, the user will see a message for every page they visit.

If you want the middleware to trigger on some routes, we can name the middleware and use that as a reference mechanism to add it to some routes. To name the middleware, while still in the app/Http/kernel.php, add the keyed property to the $routeMiddleware array. The array key is the name of the middleware, while the value should be the FQN of the middleware.

protected $routeMiddleware = [
    ...
    'doing.something' => \App\Http\Middleware\DoingSomething::class,
    ...
];

Attaching a Middleware to a Route

Take this route for example,

Route::get('posts/{something}', 'PostController@getPost');

the getPost method on the PostController class fires when the URL matches posts/{something}.

We could add our down.for.maintenance middleware by changing the second parameter of Route::get to an array which contains a middleware property and closure which processes the route.

Route::get('posts/{something}', ['middleware' => 'grown.ups.only', function () {
    return "Only big boys/girls can see this.";
}]);

By doing this, only routes matching posts/{something} will show doing something error.

Another to add middleware to routes is to call a middleware method on the route definition. Like this.

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

Middleware Parameters

Passing parameters to middlewares are quite easy. Say, for example, our middleware validates the role of a user before allowing access to a page. We could also pass a list of allowed roles to the middleware.

To pass a parameter to our middleware, after the $request and Closure parameters, we then add our variables.

public function handle($request, Closure $next, $role)
{
    if (! $request->user()->hasRole($role)) {
        // Redirect...
    }

    return $next($request);
}

To pass the variable, when attaching our middleware to routes, we do this.

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

Grouping Middlewares

At times, there might be a bunch of middlewares you apply to a couple of routes. It would be better if we could combine or group middlewares. This allows us to reuse that group of middlewares.

To group middlewares, we add a $middlewareGroups property (if it does not exist) to the Kernel class. This property takes a key-value pair array. The key represents the group name, and the value is an array of middleware FQNs. By default, Laravel provides a web, and API group.

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',
    ],
];
If we need to use this group in our application, we can then do this.
Route::group(['middleware' => ['web']], function () {
    //
});

Deferring Middlewares Response

By doing this, we first execute our middleware then we perform our action and return the response.

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

    /**
    * Perform actions here
    */

    return $response;
}

Previous: Laravel (5.7) Routing
Next: Laravel (5.7) CSRF Protection



Follow us on Facebook and Twitter for latest update.