Laravel Middleware: Put in Routes, Controller, or Elsewhere? (4 Options)

If you have a Middleware, where you should use it: in the Routes file or in the Controller? Here are the FOUR options.

I will give you the example of the default auth middleware, but the same principles apply to any Laravel or Custom Middleware class.


Option 1. Routes File.

If you read the official docs on Middleware, this is the main recommended way.

Examples:

1// Single route
2Route::get('/profile', [UserController::class, 'profile'])->middleware('auth');
3 
4// Route resource
5Route::resource('users', UserController::class)->middleware('auth');
6 
7// Route group
8Route::middleware('auth')->group(function () {
9 Route::get('/profile', [ProfileController::class, 'index']);
10 Route::post('/profile', [ProfileController::class, 'update']);
11});

Option 2. Controller Constructor

It's not mentioned in the documentation for Middleware, but the docs about Controllers show this option:

1class UserController extends Controller
2{
3 public function __construct()
4 {
5 // Assign to ALL methods in this Controller
6 $this->middleware('auth');
7 
8 // Assign only to ONE method in this Controller
9 $this->middleware('auth')->only('create');
10 
11 // Assign only to specific methods in this Controller
12 $this->middleware('auth')->only(['create', 'store']);
13 
14 // Assign to all EXCEPT specific methods in this Controller
15 $this->middleware('auth')->except('index');
16 }
17}

Notice that $this->middleware() works only if you assign it in the Constructor. If you call $this->middleware() from a specific Controller method, it will not throw any errors but Middleware will not actually work.

This option is totally valid, but personally, I prefer to put all the Middlewares in the Routes, because it's then clear where to look for all the Middlewares in one place, and not jump between Routes/Controllers to double-check. It's just a habit: always use one of the ways and don't let this question bother you.


Option 3. For All Route File: Service Provider or Kernel

There's also a global Middleware for all the Routes file, which you can assign in the RouteServiceProvider. In fact, Laravel is doing that already by default, take a look at the file that comes with Laravel:

app/Provider/RouteServiceProvider.php:

1class RouteServiceProvider extends ServiceProvider
2{
3 public function boot()
4 {
5 $this->routes(function () {
6 Route::middleware('api')
7 ->prefix('api')
8 ->group(base_path('routes/api.php'));
9 
10 Route::middleware('web')
11 ->group(base_path('routes/web.php'));
12 });
13 }
14}

See those middleware('api') and middleware('web')? So, you can assign any custom Middleware to any of the routes/xxxxx.php files.

In fact, those web and api are not individual Middlewares, they are Middleware groups. So, if you want to add your Middleware to be executed with web/api Routes only, another option is to add it to the array in the Kernel.php file:

app/Http/Kernel.php:

1class Kernel extends HttpKernel
2{
3 protected $middlewareGroups = [
4 'web' => [
5 \App\Http\Middleware\EncryptCookies::class,
6 \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
7 \Illuminate\Session\Middleware\StartSession::class,
8 \Illuminate\View\Middleware\ShareErrorsFromSession::class,
9 \App\Http\Middleware\VerifyCsrfToken::class,
10 \Illuminate\Routing\Middleware\SubstituteBindings::class,
11 
12 // <- Your middleware here
13 ],
14 
15 'api' => [
16 // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
17 'throttle:api',
18 \Illuminate\Routing\Middleware\SubstituteBindings::class,
19 
20 // <- Your middleware here
21 ],
22 ];
23}

Option 4. Globally in Kernel.php

Even more globally, you can assign the Middleware to be executed for every request.

As in the previous example, Laravel comes with some of such Middleware by default, their array is in the app/Http/Kernel.php:

app/Http/Kernel.php:

1class Kernel extends HttpKernel
2{
3 /**
4 * These middleware are run during every request to your application.
5 */
6 protected $middleware = [
7 // \App\Http\Middleware\TrustHosts::class,
8 \App\Http\Middleware\TrustProxies::class,
9 \Illuminate\Http\Middleware\HandleCors::class,
10 \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
11 \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
12 \App\Http\Middleware\TrimStrings::class,
13 \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
14 ];
15}

No comments or questions yet...

Like our articles?

Become a Premium Member for $129/year or $29/month

Recent Premium Tutorials