Laravel Route Middleware
15 May 2025 | Category: Laravel
Middleware in Laravel acts as a filter for HTTP requests, allowing you to perform tasks like authentication, authorization, logging, or input validation before a request reaches a controller or after a response is generated. Route middleware specifically applies to routes defined in routes/web.php
or routes/api.php
, providing a powerful way to control access and modify request/response behavior. This SEO-friendly, plagiarism-free guide explains Laravel route middleware, how to create and use it, and best practices. Based on Laravel 11 (as of May 2025), this tutorial is designed for beginners and intermediate developers.
What is Route Middleware?
Route middleware is a layer of code that runs during the HTTP request lifecycle, either before the request is processed by a controller or after the response is prepared. It’s called “route middleware” when applied to specific routes or route groups, enabling fine-grained control over request handling.
Common Use Cases
- Authentication: Restrict access to authenticated users.
- Authorization: Check if a user has permission for an action.
- Rate Limiting: Limit API requests to prevent abuse.
- Logging: Record request details for debugging.
- Input Validation: Sanitize or validate input data.
- CSRF Protection: Secure form submissions (applied by default in
web
routes).
How Middleware Works
Middleware sits between the HTTP request and the application’s core logic:
- Request Phase: Middleware can inspect, modify, or reject the request before it reaches the controller.
- Response Phase: Middleware can modify the response after the controller processes the request.
Laravel provides built-in middleware (e.g., auth
, throttle
) and allows you to create custom middleware for specific needs.
Built-In Middleware
Laravel includes several middleware in the app/Http/Middleware/
directory and the framework itself. Common examples:
- auth: Ensures the user is authenticated.
- guest: Restricts access to unauthenticated users.
- throttle: Limits the number of requests (e.g., 60 requests per minute).
- verified: Ensures the user’s email is verified (used with
auth
). - can: Authorizes actions using Laravel’s Gate or policies.
- web: Applied to
web.php
routes, includes session handling and CSRF protection. - api: Applied to
api.php
routes, includes throttling.
Middleware is registered in app/Http/Kernel.php
, which defines:
- Global Middleware: Runs on every request (e.g.,
CheckForMaintenanceMode
). - Route Middleware: Assigned to specific routes or groups (e.g.,
auth
,throttle
). - Middleware Groups: Bundles like
web
andapi
.
Applying Route Middleware
Route middleware can be applied to individual routes, route groups, or controllers.
1. Middleware on Individual Routes
Assign middleware using the middleware
method in routes/web.php
or routes/api.php
.
Example (in web.php
):
use App\Http\Controllers\PostController;
Route::get('/posts', [PostController::class, 'index'])->middleware('auth');
- Only authenticated users can access the
/posts
route.
Multiple middleware:
Route::get('/posts', [PostController::class, 'index'])->middleware(['auth', 'verified']);
2. Middleware on Route Groups
Group routes with shared middleware for cleaner code.
Example:
Route::middleware(['auth', 'verified'])->group(function () {
Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/create', [PostController::class, 'create'])->name('posts.create');
});
- All routes in the group require authentication and email verification.
Prefix Example (Admin routes):
Route::middleware('auth')->prefix('admin')->group(function () {
Route::get('/dashboard', [AdminController::class, 'index'])->name('admin.dashboard');
});
- Routes like
/admin/dashboard
are protected.
3. Middleware in Controllers
Apply middleware in a controller’s constructor to affect all or specific methods.
Example:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function __construct()
{
$this->middleware('auth')->except(['index', 'show']);
$this->middleware('verified')->only(['create', 'store']);
}
public function index() { /* Logic */ }
public function show($id) { /* Logic */ }
public function create() { /* Logic */ }
public function store(Request $request) { /* Logic */ }
}
auth
: Required for all methods exceptindex
andshow
.verified
: Required only forcreate
andstore
.
4. Middleware with Resource Routes
Apply middleware to resource controllers:
Route::resource('posts', PostController::class)->middleware('auth');
- All CRUD routes (
index
,store
, etc.) require authentication.
Creating Custom Middleware
You can create custom middleware for specific requirements, such as checking user roles or logging requests.
Step 1: Generate Middleware
Use Artisan to create a middleware class:
php artisan make:middleware EnsureUserIsAdmin
This creates EnsureUserIsAdmin.php
in app/Http/Middleware/
:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureUserIsAdmin
{
public function handle(Request $request, Closure $next): Response
{
if (! $request->user() || ! $request->user()->is_admin) {
abort(403, 'Unauthorized: Admin access required.');
}
return $next($request);
}
}
- handle: The main method that processes the request.
- $request: The incoming HTTP request.
- $next: Passes the request to the next middleware or controller.
- abort(403): Rejects unauthorized users with a 403 error.
Step 2: Register Middleware
Register the middleware in app/Http/Kernel.php
under $routeMiddleware
:
protected $routeMiddleware = [
// Other middleware...
'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class,
];
Step 3: Apply Middleware
Use the middleware in routes or controllers:
Route::get('/admin/dashboard', [AdminController::class, 'index'])->middleware('admin');
Or in a controller:
public function __construct()
{
$this->middleware('admin');
}
Example: Middleware with Parameters
Middleware can accept parameters for dynamic behavior.
Middleware:
public function handle(Request $request, Closure $next, $role): Response
{
if (! $request->user() || $request->user()->role !== $role) {
abort(403, 'Unauthorized: Invalid role.');
}
return $next($request);
}
Register in Kernel.php
:
'role' => \App\Http\Middleware\CheckRole::class,
Apply:
Route::get('/editor/posts', [PostController::class, 'index'])->middleware('role:editor');
- Only users with the
editor
role can access the route.
Modifying Responses in Middleware
Middleware can also modify responses after the controller processes the request.
Example:
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
// Add a custom header to the response
$response->header('X-Custom-Header', 'MyApp');
return $response;
}
Terminating Middleware
Some middleware runs after the response is sent to the browser (e.g., for logging). Define it as terminating middleware in Kernel.php
:
protected $middleware = [
\App\Http\Middleware\LogRequests::class,
];
Example:
public function handle(Request $request, Closure $next): Response
{
return $next($request);
}
public function terminate(Request $request, Response $response): void
{
\Log::info('Request processed: ' . $request->url());
}
Best Practices for Route Middleware
- Keep Middleware Focused: Each middleware should handle one responsibility (e.g., authentication, role checking).
- Use Descriptive Names: Name middleware clearly (e.g.,
EnsureUserIsAdmin
instead ofCheck
). - Leverage Middleware Groups: Use groups like
web
orapi
for common functionality. - Avoid Heavy Logic: Move complex logic to services or helpers to keep middleware lightweight.
- Test Middleware: Write tests to ensure middleware behaves as expected.
- Secure APIs: Use
throttle
and token-based authentication (e.g., Sanctum) forapi.php
routes. - Use Route Model Binding: Combine middleware with route model binding for cleaner authorization checks.
Debugging Middleware
If middleware isn’t working as expected:
- Check Registration: Ensure the middleware is registered in
Kernel.php
. - Verify Application: Confirm it’s applied to the correct route or controller.
- Debug with Logs: Add
\Log::info('Middleware reached')
in thehandle
method. - Check Order: Middleware runs in the order listed in
Kernel.php
or route definitions.
Conclusion
Route middleware in Laravel is a powerful tool for controlling HTTP requests and responses, enabling secure, modular, and maintainable applications. By using built-in middleware like auth
and throttle
, creating custom middleware for specific needs, and applying them to routes or controllers, you can enforce access control, validate input, and enhance functionality. Whether building web interfaces or APIs, middleware ensures your application is robust and efficient.
Next Steps:
- Create a custom middleware:
php artisan make:middleware CheckRole
. - Apply middleware to routes in
web.php
orapi.php
. - Explore Laravel’s official documentation for advanced middleware features.
For further learning, connect with the Laravel community on platforms like X or dive into the official Laravel documentation. Start securing your routes with middleware today!