Laravel middleware
So, what really means middleware? HTTP middleware provide a convenient mechanism for filtering HTTP requests, that are sent into the application. They work like the layers of the onion. When the request comes into the application it has to go through all the layers of this onion to get to the core. Each layer can examine the request and pass it to the next layer or reject it.
HTTP middleware are configured in the Http\Kernel
class:
In the example above we can see that for every request, that comes into our application we will have encrypted cookies, we will add queued cookies
to the response, the session will start, the errors will be shared from the session and the csrf token will be verified. All of these
middleware are included in the framework. User-defined middlewares are usually located in the app/Http/Middleware
directory.
Every middleware must implement the handle() method. This method processes the request and then passes it to the next middleware (the next layer of the onion):
Create A New Middleware
For example, we need to set a view namespace according to client user agent string: desktop or mobile. We can use artisan
command to create a new middleware:
This command will create a new SetViewNamespace
class in the app/Http/Middleware
. In this middleware, we will check the
request user agent string and store the result in the session. Then the request is passed deeper into the application by
calling the next
callback with the $request
param.
Before/After
It depends on the middleware itself when to process its logic: before or after the request. Compare these two handle()
methods of different
middleware:
In the code above the BeforeMiddleware
will perform its logic before the request is handled by the application.
But this middleware will perform its logic after the request is handled.
Registering middleware
There are three different ways to register a middleware:
- Global middleware
- Route middleware
- Middleware groups
Global middleware
If your want a middleware to be run for every HTTP request to the application, list the middleware class in the $middleware
property of the
app/Http/Kernel
class:
Route middleware
To assign a middleware to specific routes, you should first create a short-key for this middleware in $routeMiddleware
property of the
app/Http/Kernel
class:
Once the middleware has been assigned to a short-key in the Http kernel, we can use it in the middleware
key in the route options array,
in the app/Http/routes.php
file:
Instead of using a short-key we can pass a fully qualified class name:
Middleware groups
We can group our middleware under a single key to make them easier to assign to the routes. There is a $middlewareGroups
property for
this purpose. For example, we can create an admin
group:
Then, this group can be assigned to routes and controller actions:
Out of the box Laravel comes with two middleware groups: web
and api
:
Middleware groups can be assigned to routes and controller actions with the same syntax as individual middleware. They simply
make it more convenient to assign many middleware to a route at once. The web
middleware group is automatically applied to
routes.php
file in the RouteServiceProvider
:
Middleware Parameters
Middleware can receive additional parameters. For example, we can verify that the user has a given role to perform an action. To do it
we need to create a middleware that receives that role parameter in the handle()
method and pass this parameter in the routes.php
file:
App\Http\Middleware\RoleMiddleware:
App\Http\routes.php:
Terminable Middleware
If we need to do some work after the HTTP response has been sent to the browser, we need to define a terminable
middleware. To do it we can simply add a terminate()
method to the middleware. For example, Laravel comes with the
Illuminate\Session\Middleware\StartSession
middleware. It writes session data after the response has been sent:
The terminate()
method receives both the request and the response objects. After defining a terminable middleware,
it should be listed in the global middlewares in the Http kernel.