Middleware - Laravel 12.x - The PHP Framework For Web Artisans
Middleware - Laravel 12.x - The PHP Framework For Web Artisans
Middleware
# Introduction
# Defining Middleware
# Registering Middleware
# Global Middleware
# Assigning Middleware to Routes
# Middleware Groups
# Middleware Aliases
# Sorting Middleware
# Middleware Parameters
# Terminable Middleware
# Introduction
Middleware provide a convenient mechanism for inspecting and 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 your application's login screen. However, if the
user is authenticated, the middleware will allow the request to proceed further into the
application.
# Defining Middleware
To create a new middleware, use the make:middleware Artisan command:
if the supplied token input matches a specified value. Otherwise, we will redirect the
users back to the /home URI:
1 <?php
2
3 namespace App\Http\Middleware;
4
5 use Closure;
6 use Illuminate\Http\Request;
7 use Symfony\Component\HttpFoundation\Response;
8
9 class EnsureTokenIsValid
10 {
11 /**
12 * Handle an incoming request.
13 *
14 * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\Htt
15 */
16 public function handle(Request $request, Closure $next): Response
17 {
18 if ($request->input('token') !== 'my-secret-token') {
19 return redirect('/home');
20 }
21
22 return $next($request);
23 }
24 }
As you can see, if the given token does not match our secret token, the middleware will
return an HTTP redirect to the client; otherwise, the request will be passed further into
the application. To pass the request deeper into the application (allowing the
middleware to "pass"), you should call the $next callback with the $request .
It's best to envision middleware as a series of "layers" HTTP requests must pass
through before they hit your application. Each layer can examine the request and even
reject it entirely.
All middleware are resolved via the service container, so you may type-hint any
dependencies you need within a middleware's constructor.
1 <?php
2
3 namespace App\Http\Middleware;
4
5 use Closure;
6 use Illuminate\Http\Request;
7 use Symfony\Component\HttpFoundation\Response;
8
9 class BeforeMiddleware
10 {
11 public function handle(Request $request, Closure $next): Response
12 {
13 // Perform action
14
15 return $next($request);
16 }
17 }
However, this middleware would perform its task after the request is handled by the
application:
1 <?php
2
3 namespace App\Http\Middleware;
4
5 use Closure;
6 use Illuminate\Http\Request;
7 use Symfony\Component\HttpFoundation\Response;
8
9 class AfterMiddleware
10 {
11 public function handle(Request $request, Closure $next): Response
12 {
13 $response = $next($request);
14
15 // Perform action
16
17 return $response;
18 }
19 }
# Registering Middleware
# Global Middleware
If you want a middleware to run during every HTTP request to your application, you
may append it to the global middleware stack in your application's bootstrap/app.php
file:
1 use App\Http\Middleware\EnsureTokenIsValid;
2
3 ->withMiddleware(function (Middleware $middleware) {
4 $middleware->append(EnsureTokenIsValid::class);
5 })
middleware assigned to your application's routes. The append method adds the
middleware to the end of the list of global middleware. If you would like to add a
middleware to the beginning of the list, you should use the prepend method.
You may assign multiple middleware to the route by passing an array of middleware
names to the middleware method:
1 Route::get('/', function () {
2 // ...
3 })->middleware([First::class, Second::class]);
# Excluding Middleware
When assigning middleware to a group of routes, you may occasionally need to
prevent the middleware from being applied to an individual route within the group. You
may accomplish this using the withoutMiddleware method:
1 use App\Http\Middleware\EnsureTokenIsValid;
2
3 Route::middleware([EnsureTokenIsValid::class])->group(function () {
4 Route::get('/', function () {
5 // ...
6 });
7
8 Route::get('/profile', function () {
9 // ...
10 })->withoutMiddleware([EnsureTokenIsValid::class]);
11 });
You may also exclude a given set of middleware from an entire group of route
definitions:
1 use App\Http\Middleware\EnsureTokenIsValid;
2
3 Route::withoutMiddleware([EnsureTokenIsValid::class])->group(function () {
4 Route::get('/profile', function () {
5 // ...
6 });
7 });
The withoutMiddleware method can only remove route middleware and does not apply
to global middleware.
# Middleware Groups
Sometimes you may want to group several middleware under a single key to make
them easier to assign to routes. You may accomplish this using the appendToGroup
method within your application's bootstrap/app.php file:
1 use App\Http\Middleware\First;
2 use App\Http\Middleware\Second;
3
4 ->withMiddleware(function (Middleware $middleware) {
5 $middleware->appendToGroup('group-name', [
6 First::class,
7 Second::class,
8 ]);
9
10 $middleware->prependToGroup('group-name', [
11 First::class,
12 Second::class,
13 ]);
14 })
Middleware groups may be assigned to routes and controller actions using the same
syntax as individual middleware:
1 Route::get('/', function () {
2 // ...
3 })->middleware('group-name');
4
5 Route::middleware(['group-name'])->group(function () {
6 // ...
7 });
Illuminate\Cookie\Middleware\EncryptCookies
Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse
Illuminate\Session\Middleware\StartSession
Illuminate\View\Middleware\ShareErrorsFromSession
Illuminate\Foundation\Http\Middleware\ValidateCsrfToken
Illuminate\Routing\Middleware\SubstituteBindings
Illuminate\Routing\Middleware\SubstituteBindings
If you would like to append or prepend middleware to these groups, you may use the
web and api methods within your application's bootstrap/app.php file. The web and api
You may even replace one of Laravel's default middleware group entries with a custom
middleware of your own:
1 use App\Http\Middleware\StartCustomSession;
2 use Illuminate\Session\Middleware\StartSession;
3
4 $middleware->web(replace: [
5 StartSession::class => StartCustomSession::class,
6 ]);
1 $middleware->web(remove: [
2 StartSession::class,
3 ]);
By default, the web and api middleware groups are automatically applied to your
application's corresponding routes/web.php and routes/api.php files by the
bootstrap/app.php file.
# Middleware Aliases
You may assign aliases to middleware in your application's bootstrap/app.php file.
Middleware aliases allow you to define a short alias for a given middleware class, which
can be especially useful for middleware with long class names:
1 use App\Http\Middleware\EnsureUserIsSubscribed;
2
3 ->withMiddleware(function (Middleware $middleware) {
4 $middleware->alias([
5 'subscribed' => EnsureUserIsSubscribed::class
6 ]);
7 })
Once the middleware alias has been defined in your application's bootstrap/app.php
file, you may use the alias when assigning the middleware to routes:
1 Route::get('/profile', function () {
2 // ...
3 })->middleware('subscribed');
For convenience, some of Laravel's built-in middleware are aliased by default. For
example, the auth middleware is an alias for the
Illuminate\Auth\Middleware\Authenticate middleware. Below is a list of the default
middleware aliases:
Alias Middleware
auth Illuminate\Auth\Middleware\Authenticate
auth.basic Illuminate\Auth\Middleware\AuthenticateWithBasicAuth
auth.session Illuminate\Session\Middleware\AuthenticateSession
cache.headers Illuminate\Http\Middleware\SetCacheHeaders
can Illuminate\Auth\Middleware\Authorize
guest Illuminate\Auth\Middleware\RedirectIfAuthenticated
password.confirm Illuminate\Auth\Middleware\RequirePassword
precognitive Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequest
signed Illuminate\Routing\Middleware\ValidateSignature
subscribed \Spark\Http\Middleware\VerifyBillableIsSubscribed
Illuminate\Routing\Middleware\ThrottleRequests or
throttle
Illuminate\Routing\Middleware\ThrottleRequestsWithRedis
Alias Middleware
verified Illuminate\Auth\Middleware\EnsureEmailIsVerified
# Sorting Middleware
Rarely, you may need your middleware to execute in a specific order but not have
control over their order when they are assigned to the route. In these situations, you
may specify your middleware priority using the priority method in your application's
bootstrap/app.php file:
# Middleware Parameters
Middleware can also receive additional parameters. For example, if your application
needs to verify that the authenticated user has a given "role" before performing a given
action, you could create an EnsureUserHasRole middleware that receives a role name as
an additional argument.
Additional middleware parameters will be passed to the middleware after the $next
argument:
1 <?php
2
3 namespace App\Http\Middleware;
4
5 use Closure;
6 use Illuminate\Http\Request;
7 use Symfony\Component\HttpFoundation\Response;
8
9 class EnsureUserHasRole
10 {
11 /**
12 * Handle an incoming request.
13 *
14 * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\Htt
15 */
16 public function handle(Request $request, Closure $next, string $role)
17 {
18 if (! $request->user()->hasRole($role)) {
19 // Redirect...
20 }
21
22 return $next($request);
23 }
24
25 }
Middleware parameters may be specified when defining the route by separating the
middleware name and parameters with a : :
1 use App\Http\Middleware\EnsureUserHasRole;
2
3 Route::put('/post/{id}', function (string $id) {
4 // ...
5 })->middleware(EnsureUserHasRole::class.':editor');
Multiple parameters may be delimited by commas:
# Terminable Middleware
Sometimes a middleware may need to do some work after the HTTP response has
been sent to the browser. If you define a terminate method on your middleware and
your web server is using FastCGI, the terminate method will automatically be called
after the response is sent to the browser:
1 <?php
2
3 namespace Illuminate\Session\Middleware;
4
5 use Closure;
6 use Illuminate\Http\Request;
7 use Symfony\Component\HttpFoundation\Response;
8
9 class TerminatingMiddleware
10 {
11 /**
12 * Handle an incoming request.
13 *
14 * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\Htt
15 */
16 public function handle(Request $request, Closure $next): Response
17 {
18 return $next($request);
19 }
20
21 /**
22 * Handle tasks after the response has been sent to the browser.
23 */
24 public function terminate(Request $request, Response $response): void
25 {
26 // ...
27 }
28 }
The terminate method should receive both the request and the response. Once you
have defined a terminable middleware, you should add it to the list of routes or global
middleware in your application's bootstrap/app.php file.
When calling the terminate method on your middleware, Laravel will resolve a fresh
instance of the middleware from the service container. If you would like to use the same
middleware instance when the handle and terminate methods are called, register the
middleware with the container using the container's singleton method. Typically this
should be done in the register method of your AppServiceProvider :
1 use App\Http\Middleware\TerminatingMiddleware;
2
3 /**
4 * Register any application services.
5 */
6 public function register(): void
7 {
8 $this->app->singleton(TerminatingMiddleware::class);
9 }
Resources Products
Documentation Cloud
Blog Nightwatch
Partners Nova
News
Larabelles
Jobs
Careers
Packages
Cashier Sail
Dusk Sanctum
Horizon Socialite
Octane Telescope
Scout Pulse
Pennant Reverb
Pint Echo