Middleware in Laravel
Table of Contents
- Introduction to Middleware
- What is Middleware
- Types of Middleware
- Creating Middleware
- Registering Middleware
- Global Middleware
- Route-Specific Middleware
- Middleware Parameters
- Middleware Groups
- Authentication Middleware
- Request Modification
- Response Modification
- Terminating Middleware
- Middleware Order and Execution
- Advanced Middleware Techniques
- Common Use Cases
- Best Practices
- Conclusion
Introduction to Middleware
Middleware provides a mechanism for filtering HTTP requests entering your application. It acts as a bridge between a request and a response, allowing you to inspect, modify, or halt the request processing.
What is Middleware
A middleware is a series of “layers” that requests must pass through before reaching their final destination:
Request → Middleware 1 → Middleware 2 → Middleware 3 → Application → Response
Types of Middleware
- Built-in Middleware
- Authentication
- CSRF Protection
- Encryption
- Throttling
- Custom Middleware
- User-defined request filters
- Custom authentication checks
- Logging and monitoring
Creating Middleware
Generate middleware using Artisan:
php artisan make:middleware CheckAge
Implement middleware logic:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CheckAge
{
public function handle(Request $request, Closure $next)
{
if ($request->age < 18) {
return redirect('home');
}
return $next($request);
}
}
Registering Middleware
Register in app/Http/Kernel.php
:
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
'age' => \App\Http\Middleware\CheckAge::class,
];
Global Middleware
Applied to every request:
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
];
Route-Specific Middleware
Apply to specific routes:
Route::get('/profile', 'ProfileController@index')
->middleware('auth', 'age');
// Or in controller constructor
public function __construct()
{
$this->middleware('auth')->except(['index']);
}
Middleware Parameters
Pass additional parameters:
class CheckRole
{
public function handle($request, Closure $next, $role)
{
if (!$request->user()->hasRole($role)) {
return redirect('home');
}
return $next($request);
}
}
// Usage
Route::get('/admin', 'AdminController@index')
->middleware('role:admin');
Middleware Groups
Group multiple middleware:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
],
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
Authentication Middleware
Basic authentication check:
public function handle($request, Closure $next)
{
if (!Auth::check()) {
return redirect('login');
}
// Additional role-based checks
if (!$request->user()->isAdmin()) {
abort(403, 'Unauthorized action');
}
return $next($request);
}
Request Modification
Modify request before processing:
public function handle($request, Closure $next)
{
// Transform or validate request
$request->merge([
'normalized_email' => strtolower($request->email)
]);
return $next($request);
}
Response Modification
Modify response after processing:
public function handle($request, Closure $next)
{
$response = $next($request);
// Add custom headers
$response->header('X-Custom-Header', 'Value');
return $response;
}
Terminating Middleware
Perform actions after response:
public function terminate($request, $response)
{
// Perform cleanup or logging
Log::info('Request processed');
}
Middleware Order and Execution
Middleware executes in a specific order:
- Global Middleware
- Route Middleware
- Controller Middleware
Advanced Middleware Techniques
- Dynamic middleware generation
- Conditional middleware application
- Middleware composition
- Dependency injection
Common Use Cases
- User authentication
- Role-based access control
- Request logging
- CORS handling
- Rate limiting
- HTTPS enforcement
Best Practices
- Keep middleware focused and single-purpose
- Avoid complex logic in middleware
- Use middleware for cross-cutting concerns
- Leverage dependency injection
- Test middleware thoroughly
Conclusion
Middleware in Laravel provides a powerful, flexible mechanism for filtering and transforming HTTP requests. By creating modular, reusable request processors, developers can implement complex application logic with clean, maintainable code.
The middleware system represents Laravel’s commitment to providing elegant solutions for common web development challenges, enabling developers to create robust, secure, and performant applications.