A detailed note on Middlewares in Laravel 5.2
Introduction
Middlewares in Laravel is nothing but a simple mechanism that helps to filter the HTTP requests and alter the business logic or executes some action/logics based on the written conditions. In other words we could say the middlewares are logical layer around our application that analyze the http requests and alter the application business logic.
A good example we could say about middleware is authentication. We can check each request to our application using the Laravel authentication middleware. Authentication middleware checks each request that has been defined under ‘Auth’ middleware, in route file. And before processing the particular request, Auth middleware confirms whether the user is logged in or authenticated to access the requested page. If not, the user will get redirected to login page.
Laravel 5 have built-in middlewares for authentication, CSRF protection etc. You can see these middlewares in app/Http/Middleware directory of Laravel-5. We could also define and use our own custom middlewares in our laravel application for performing various functionalities.
Middlewares can either executes the logics before or after the particular incoming http request is handled. Based on this ability of middlewares can be classified as Before / After Middleware. We will start with learning how to create a middleware then we will jump on defining and using a middleware in our application.
Creating a middleware :
Creating a middleware is simple ! Open up your terminal switch to your project directory and run the following artisan command.
php artisan make:middleware nameOfMiddleware
This simple command will generate a middleware within your project’s app/Http/Middleware directory with specified middleware name.
Defining a Middleware:
Once we have run the artisan make command for middleware we will get a file generated with following structure.
<?php namespace App\Http\Middleware; use Closure; class SampleMiddleware { /** * Run the request filter. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { //Code return $next($request); } }
We should have to write our business logics within the handle method of our middleware.
Before Middleware :
Middlewares which executes the business logics before the particular incoming http request is handled is called as Before Middleware.
The code structure of Before Middleware would look like as follows :
<?php namespace App\Http\Middleware; use Closure; class BeforeMiddleware implements Middleware { public function handle($request, Closure $next) { // code for Performing business logics return $next($request); } }
After Middleware :
Middlewares which executes the business logics after the particular incoming http request is handled is called as after Middleware.
The code structure of After Middleware would look like as follows :
<?php namespace App\Http\Middleware; use Closure; class AfterMiddleware implements Middleware { public function handle($request, Closure $next) { $response = $next($request); // code for Performing business logics return $response; } }
Registering a Middleware :
We can either apply this extra layer of logics (Middlewares) for all the HTTP request that coming to our application, or we could assign the defined middlewares for specific routes.
Based on this Middlewares can be classified into –
- Global Middlewares
- specific route Middlewares
Global Middlewares
Global middlewares are middlewares that executes for each and every request to our application.
Specific route Middlewares
Specific route Middlewares are middlewares that executes for specified predefined routes.
Setting-up Global middlewares :
Setting a global middleware that executes for every request is simple. Open up your projects app/Http/Kernel.php file. You could see 2 different properties defined in the class ‘$middleware’ and ‘$routeMiddleware’.
Simply append your middlewares to the $middleware section as comma separated.
protected $middleware = [ 'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode', 'Illuminate\Cookie\Middleware\EncryptCookies', 'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse', 'Illuminate\Session\Middleware\StartSession', 'Illuminate\View\Middleware\ShareErrorsFromSession', 'App\Http\Middleware\VerifyCsrfToken', ];
Setting-up route Middlewares :
In Order to set up route middlewares you should append your middlewares to ‘$routeMiddleware’ property of Kernel class in your project’s app/Http/Kernel.php file along with the key of our choice. The key is added to represent the specific route for which the particular middleware has to be executed.
protected $routeMiddleware = [ 'auth' => 'App\Http\Middleware\Authenticate', 'auth.basic'=> 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth', 'guest' => 'App\Http\Middleware\RedirectIfAuthenticated', ];
For example let us say we have a middleware SampleMiddleware. We can append the following string to the $routeMiddleware property.
'sampleroutekey' => 'App\Http\Middleware\SampleMiddleware',
This means the SampleMiddleware will execute when the particular route with the key “sampleroutekey” is requested. Once the middleware is appended to the $routeMiddleware property, you should have to specify the key given for that middleware within the particular route’s optional array field. As follows :
- open up your project’s route file (app/Http/routes.php)
- Add the key to the optional array field of the route for which you need to execute the particular middleware.Route::get('test/samplepage', ['middleware' => 'sampleroutekey', function(){ //code }]);
Middleware Groups :
Now Laravel 5.2 is released with a new feature called middleware groups. As the name indicate the middleware group is a grouping of multiple middlewares (of same kind/category) which are indicated by a single key and this Group key can be assigned to single route or a set of routes, so that multiple middlewares can be simply assigned to a single/group of routes at once using a single key.
In laravel 5.2 app/Http/Kernel.php file you could see $middlewareGroups array, in which you can group the middlewares as key value pair as below.
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \App\Http\Middleware\VerifyCsrfToken::class, ] 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \App\Http\Middleware\VerifyCsrfToken::class, ] ];
Middleware groups can be assigned to routes and controller actions using the same syntax as individual middleware.
Laravel 5.2 ships with 2 middleware group ‘web’ and ‘api’ by default. The ‘web’ middleware group includes set of middleware those are specific for website. And ‘api’ stands specifically with the middlewares helpful for API development.
Laravel 5.2 has a new rate limiter middleware included with the framework which comes under the middleware group ‘api’. This rate limiter API helps to restrict the number of requests that can be made to a route in a given time interval(in minutes) from a specific IP address. By default the ‘api’ middleware group has the following structure, which allows only 60 requests from 1 IP in a minute.
'api' => [ 'throttle:60,1', ]
Terminable Middleware :
Terminable Middlewares in laravel 5.* are helpful if we need to invoke some functionalities after the HTTP response has been sent to browser. We could define the terminable middleware By adding a “terminate” method as follows. And then add the middleware to list of global middlewares.
public function terminate($request, $response){ // code for Performing business logics }
Conclusion :
Middlewares in laravel 5.* is a very helpful feature introduced by Laravel team, which helps developers to play nicely with their logics on the routes.
Laravel’s different default middlewares for authentication, csrf protection, sessions, cookies management, different request filtering etc. simplifies the development process. We could write our own middlewares to implement our logics as well. These options also allows us to reuse the code, reduce the number of lines of codes and the grouping feature allow developers to simply assign different logics to a single/ group of routes. Hence, the Middlewares play a great role to make the application development much easier and faster.
Cheers !!