Skip to main content
Tutorial Free

Middleware in Laravel: Main Things to Know

June 05, 2025
4 min read

In Laravel, you often need to check things before users reach the Controller. For that, you would use Middleware. Let me explain how it works with examples.

Here are the examples you would check:

  • Is the user logged in?
  • Does the user have admin rights?
  • Is the API request valid?

So, Middleware can help as a security checkpoint that can inspect, modify, or reject requests.


Example: Built-in "Auth" Middleware

Example code without Middleware:

routes/web.php:

Route::get('/dashboard', function () {
if (!auth()->check()) {
return redirect('/login');
}
return view('dashboard');
});

Same example with auth Middleware that comes with Laravel:

routes/web.php:

Route::get('/dashboard', function () {
return view('dashboard');
})->middleware('auth');

Using Middleware is shorter and may be reusable in multiple routes.

The auth Middleware is an example from the framework core, and there are a few more useful built-in Middleware classes:

  • auth - User must be logged in: ->middleware('auth')
  • guest - The opposite - user must NOT be logged in: ->middleware('guest')
  • throttle - Rate limiting how many attempts per minute: ->middleware('throttle:60,1')
  • can - Permission Gate/Policy check: ->middleware('can:edit,post')
  • verified - Email verified: ->middleware('verified')

You can also create your custom Middleware.


Custom Middleware Example

Goal: Restrict certain features to admin users only.

Generate the Middleware:

php artisan make:middleware CheckAdmin

Define the logic:

app/Http/Middleware/CheckAdmin.php:

namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
class CheckAdmin
{
public function handle(Request $request, Closure $next): Response
{
if (!$request->user() || !$request->user()->isAdmin()) {
abort(403, 'Admin access required');
}
 
return $next($request);
}
}

As you can see, in the handle() method, you either restrict access or allow the request to proceed with the return $next($request); statement.


Registering Middleware with Alias

In Laravel 11+, all Middleware configuration happens in the bootstrap/app.php file using the withMiddleware() method.

You come up with an alias name for your Middleware class, to be used in the Routes, like the auth example above.

bootstrap/app.php

use App\Http\Middleware\CheckAdmin;
 
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function ($middleware) {
$middleware->alias([
'admin' => CheckAdmin::class,
]);
})
->create();

Then, use that alias in the routes:

routes/web.php:

// Single Middleware
Route::get('/admin/users',
[UserController::class, 'index']
)->middleware('admin');
 
// Multiple Middleware
Route::get('/admin/settings', SettingController::class)
-> Middleware (['auth', 'admin']);

Using Middleware with No Alias

Creating the alias is optional. You can also use Middleware by directly referencing the full class name.

routes/web.php:

use App\Http\Middleware\CheckAdmin;
 
// ...
 
Route::get('/admin/users',
[UserController::class, 'index']
)->middleware(CheckAdmin::class);

You can also combine the alias and non-alias references.

routes/web.php:

use App\Http\Middleware\ValidateApiToken;
 
// ...
 
Route::get('/api/data', function () {
return response()->json(['data' => 'example']);
})->middleware([ValidateApiToken::class, 'throttle:60,1']);

Middleware on Route Groups

Apply Middleware to multiple routes at once:

routes/web.php:

Route::middleware(['auth', 'admin'])->group(function () {
Route::get('/admin/dashboard', function () {
return view('admin.dashboard');
});
 
Route::get('/admin/users', function () {
return view('admin.users');
});
});

Middleware with Parameters

Some Middleware requires additional data to work properly. For example, you can check for a role by passing $role as a parameter.

app/Http/Middleware/CheckRole.php

namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
class CheckRole
{
public function handle(Request $request, Closure $next, string $role): Response
{
if (!$request->user()->hasRole($role)) {
abort(403, "Requires {$role} role");
}
 
return $next($request);
}
}

routes/web.php:

Route::put('/posts/{post}', function ($post) {
// Edit post
})->middleware('role:editor');

Global Middleware

You may also want to add global Middleware that runs on every HTTP request to your application.

bootstrap/app.php

use App\Http\Middleware\LogRequests;
 
->withMiddleware(function ($middleware) {
$middleware->append(LogRequests::class);
})

More in the Docs

For more options and features of Middleware, please read the official Laravel documentation.

Enjoyed This Tutorial?

Get access to all premium tutorials, video and text courses, and exclusive Laravel resources. Join our community of 10,000+ developers.

Recent Courses

Comments & Discussion

LN
Loganathan Natarajan ✓ Link copied!

Thank you

GS
Gamal Sobhy ✓ Link copied!

thank you very useful article

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.