This tutorial is out of date and no longer maintained.
HTTP Middlewares provide a convenient mechanism for filtering HTTP requests entering your application. Laravel, for example, has a middleware for verifying a user’s authentication.
These are some cases where I have had to resort to using middleware. There are many more cases where you would like to use a middleware.
By the end of this article, you should be able to create a middleware, register it, and use it in your projects. We will be illustrating the creation till usage of middlewares by creating one of our own. Our middleware will enable maintenance either site-wide or on some routes.
Thanks to artisan
, creating middlewares in Laravel is easy. All we need to do is open a terminal in the project root and run the following command.
- php artisan make:middleware <MiddlewareName>
Replace <MiddlewareName>
with the actual name of the middleware.
This command creates our middleware class in app/Http/Middleware
. To create our own middleware (which we will call DownForMaintenance
, we can.
- php artisan make:middleware DownForMaintenance
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.
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\DownForMaintenance::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 = [
...
'down.for.maintenance' => \App\Http\Middleware\DownForMaintenance::class,
...
];
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 that 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 the down for maintenance 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']);
Passing parameters to middlewares is 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) {
//
}]);
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 () {
//
});
If you noticed, throughout this article, we perform an action then execute our middleware. But we could also execute our middleware first before returning a response.
public function handle($request, Closure $next)
{
$response = $next($request);
/**
* Perform actions here
*/
return $response;
}
By doing this, we first execute our middleware then we perform our action and return the response.
The use cases mentioned above are just a few examples. You can create a middleware to do so much more than what I have listed above.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!