Laravel Middleware Uitgelicht: Authenticatie, Rate Limiting en Eigen Middleware
Beheers Laravel middleware met praktische voorbeelden over authenticatie-guards, rate limiting met throttle, eigen middleware bouwen, PHP-attributen in Laravel 13 en geavanceerde patronen voor productieapplicaties.

Laravel middleware fungeert als filterlaag tussen inkomende HTTP-verzoeken en de applicatielogica. Elk verzoek passeert een pipeline van middleware-klassen voordat het een controller bereikt, en elk antwoord reist terug door dezelfde pipeline. Het begrijpen van dit mechanisme is essentieel voor het bouwen van veilige, performante Laravel-applicaties.
Middleware onderschept HTTP-verzoeken voordat ze routes bereiken. Laravel registreert alle middleware in bootstrap/app.php via een fluent API. Ingebouwde middleware regelt authenticatie, CSRF-bescherming, sessiebeheer en rate limiting standaard.
Hoe de Laravel Middleware Pipeline werkt
De Laravel HTTP-kernel verwerkt elk verzoek door een stack van middleware. Elke middleware ontvangt het verzoek, voert zijn logica uit en geeft het verzoek door aan de volgende laag via $next($request) of onderbreekt de pipeline door direct een antwoord te retourneren.
Deze architectuur volgt het Chain of Responsibility-pattern. Middleware kan voor het verzoek de controller bereikt (bijv. authenticatiecontroles), na het genereren van het antwoord (bijv. headers toevoegen), of in beide fasen actief zijn.
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use IlluminateSupportFacadesLog;
use SymfonyComponentHttpFoundationResponse;
class LogRequestTime
{
public function handle(Request $request, Closure $next): Response
{
$start = microtime(true); // Capture start time
$response = $next($request); // Pass to next middleware
$duration = microtime(true) - $start;
Log::info('Request completed', [
'url' => $request->url(),
'method' => $request->method(),
'duration' => round($duration * 1000, 2) . 'ms',
]);
return $response; // Return response up the stack
}
}Deze middleware omhult het verzoek: het registreert de starttijd voor verwerking en logt de duur na het terugkeren van het antwoord. Dit before/after-pattern is centraal in hoe middleware werkt.
Authentication Middleware: Routes Beschermen
Laravel levert de auth-middleware-alias, gekoppeld aan IlluminateAuthMiddlewareAuthenticate. Het toepassen op een route zorgt ervoor dat alleen geauthenticeerde gebruikers toegang hebben. Niet-geauthenticeerde gebruikers ontvangen een 401-antwoord (API) of worden doorgestuurd naar de loginpagina (web).
use AppHttpControllersDashboardController;
use AppHttpControllersProfileController;
// Single route protection
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware('auth');
// Group protection for multiple routes
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'show']);
Route::put('/profile', [ProfileController::class, 'update']);
Route::delete('/profile', [ProfileController::class, 'destroy']);
});Multi-Guard Authenticatie
Applicaties met meerdere gebruikerstypen (adminpaneel, klantengebied, API) profiteren van guard-gebaseerde authenticatie. De auth-middleware accepteert een guard-parameter om te specificeren welke authenticatiedriver gebruikt moet worden.
// API routes use the 'sanctum' guard
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', fn (Request $request) => $request->user());
Route::apiResource('/orders', OrderController::class);
});
// routes/web.php
// Admin routes use a custom 'admin' guard
Route::middleware('auth:admin')->prefix('admin')->group(function () {
Route::get('/dashboard', [AdminController::class, 'index']);
Route::get('/users', [AdminController::class, 'users']);
});De guard-parameter na de dubbele punt vertelt Laravel tegen welke authenticatieconfiguratie gevalideerd moet worden. Dit houdt de authenticatielogica overzichtelijk en gescheiden over verschillende delen van de applicatie.
De guest-middleware is het omgekeerde van auth: het laat alleen niet-geauthenticeerde gebruikers door. Toepassing op login- en registratieroutes voorkomt dat reeds ingelogde gebruikers deze pagina's bereiken.
Rate Limiting met Throttle Middleware
Laravel middleware rate limiting beschermt routes tegen misbruik met de ingebouwde throttle-middleware. De eenvoudigste vorm accepteert twee parameters: het maximale aantal verzoeken en het tijdvenster in minuten.
// Allow 60 requests per minute per user
Route::middleware('throttle:60,1')->group(function () {
Route::get('/posts', [PostController::class, 'index']);
Route::get('/posts/{post}', [PostController::class, 'show']);
});
// Stricter limit for write operations
Route::middleware(['auth:sanctum', 'throttle:10,1'])->group(function () {
Route::post('/posts', [PostController::class, 'store']);
Route::put('/posts/{post}', [PostController::class, 'update']);
});Benoemde Rate Limiters voor Geavanceerde Controle
Het definieren van benoemde rate limiters in AppServiceProvider geeft gedetailleerde controle over limieten gebaseerd op gebruikerscontext. Deze aanpak is flexibeler dan inline throttle-parameters. Zie de officiele rate limiting-documentatie voor extra opties.
use IlluminateCacheRateLimitingLimit;
use IlluminateSupportFacadesRateLimiter;
use IlluminateHttpRequest;
public function boot(): void
{
// API rate limiter with tiered access
RateLimiter::for('api', function (Request $request) {
$user = $request->user();
if ($user?->hasSubscription('enterprise')) {
return Limit::perMinute(500)->by($user->id); // Enterprise: 500/min
}
if ($user) {
return Limit::perMinute(100)->by($user->id); // Authenticated: 100/min
}
return Limit::perMinute(20)->by($request->ip()); // Anonymous: 20/min
});
// Login limiter to prevent brute force
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by($request->ip()) // Key by IP address
->response(function () { // Custom exceeded response
return response()->json([
'message' => 'Too many login attempts. Try again in a minute.',
], 429);
});
});
}Het toepassen van benoemde limiters op routes gebruikt de throttle:naam-syntax:
Route::middleware('throttle:api')->group(function () {
Route::apiResource('/posts', PostController::class);
});
// routes/web.php
Route::middleware('throttle:login')
->post('/login', [AuthController::class, 'login']);De gelaagde rate limiter hierboven demonstreert een productiepatroon: enterprise-gebruikers krijgen hogere limieten, geauthenticeerde gebruikers krijgen gematigde limieten, en anonieme verzoeken worden agressief beperkt. De by()-methode bepaalt de rate limit-sleutel, met gebruikers-ID voor geauthenticeerde gebruikers en IP-adres als fallback.
Klaar om je Laravel gesprekken te halen?
Oefen met onze interactieve simulatoren, flashcards en technische tests.
Eigen Middleware vanaf Scratch Bouwen
Het maken van eigen middleware dekt scenario's die ingebouwde middleware niet afhandelt. Het make:middleware-Artisan-commando genereert een nieuwe klasse met de juiste structuur.
php artisan make:middleware EnsureUserHasRoleRolgebaseerde Toegangscontrole Middleware
Een veelvoorkomend patroon voor eigen middleware is rolgebaseerde autorisatie op routeniveau, waarbij rolnamen als parameters worden geaccepteerd.
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use SymfonyComponentHttpFoundationResponse;
class EnsureUserHasRole
{
public function handle(Request $request, Closure $next, string ...$roles): Response
{
$user = $request->user();
if (! $user || ! $user->hasAnyRole($roles)) {
abort(403, 'Insufficient permissions.');
}
return $next($request);
}
}De variadische ...$roles-parameter maakt het doorgeven van meerdere rollen mogelijk, gescheiden door komma's. Registratie en gebruik zien er zo uit:
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'role' => AppHttpMiddlewareEnsureUserHasRole::class,
]);
})
// routes/web.php
Route::middleware('role:admin')->group(function () {
Route::get('/admin', [AdminController::class, 'index']);
});
// Multiple roles: admin OR editor can access
Route::middleware('role:admin,editor')->group(function () {
Route::resource('/articles', ArticleController::class);
});Request Transformatie Middleware
Middleware kan het verzoek wijzigen voordat het de controller bereikt. Een JSON API-middleware die content type-headers afdwingt en string-invoer trimt:
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use SymfonyComponentHttpFoundationResponse;
class ApiRequestSanitizer
{
public function handle(Request $request, Closure $next): Response
{
// Reject non-JSON requests on API routes
if (! $request->expectsJson() && $request->isMethod('POST')) {
return response()->json(
['error' => 'Content-Type must be application/json'],
415
);
}
// Trim all string inputs
$input = $request->all();
array_walk_recursive($input, function (&$value) {
if (is_string($value)) {
$value = trim($value);
}
});
$request->merge($input);
return $next($request);
}
}Deze middleware handelt twee zaken af: het valideert het content type voor POST-verzoeken en sanitiseert alle string-invoer door witruimte te verwijderen.
Middleware Registratie in bootstrap/app.php
Laravel centraliseert alle middleware-registratie in bootstrap/app.php. Dit verving de oudere app/Http/Kernel.php-aanpak die bestond voor Laravel 11. Dezelfde fluent API werkt in Laravel 12 en 13.
use IlluminateFoundationApplication;
use IlluminateFoundationConfigurationMiddleware;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
// Global middleware (runs on every request)
$middleware->append(
AppHttpMiddlewareLogRequestTime::class
);
// Add to the 'web' middleware group
$middleware->web(append: [
AppHttpMiddlewareTrackPageViews::class,
]);
// Add to the 'api' middleware group
$middleware->api(prepend: [
AppHttpMiddlewareApiRequestSanitizer::class,
]);
// Register aliases for route-level use
$middleware->alias([
'role' => AppHttpMiddlewareEnsureUserHasRole::class,
'subscribed' => AppHttpMiddlewareEnsureUserIsSubscribed::class,
]);
// Control execution order
$middleware->priority([
IlluminateSessionMiddlewareStartSession::class,
IlluminateAuthMiddlewareAuthenticate::class,
AppHttpMiddlewareEnsureUserHasRole::class,
]);
})
->create();De priority-array is belangrijk wanneer meerdere middleware aan dezelfde route zijn toegewezen. Laravel sorteert ze volgens deze lijst, zodat de sessie wordt gestart voor authenticatie en authenticatie compleet is voor rolcontroles.
Middleware wordt uitgevoerd in de volgorde van registratie. Voor route-level middleware overschrijft de priority-array de standaardvolgorde. Plaats authenticatie altijd voor autorisatie-middleware om rolcontroles op niet-geauthenticeerde verzoeken te voorkomen.
PHP-Attributen voor Middleware in Laravel 13
Laravel 13 introduceerde het #[Middleware]-PHP-attribuut voor het declareren van middleware direct op controllerklassen en -methoden. Deze aanpak houdt middleware-configuratie samen met de code die het beschermt, waardoor autorisatieregels leesbaarder en onderhoudsvriendelijker worden.
namespace AppHttpControllers;
use AppModelsComment;
use AppModelsPost;
use IlluminateRoutingAttributesControllersAuthorize;
use IlluminateRoutingAttributesControllersMiddleware;
#[Middleware('auth')]
class CommentController
{
#[Middleware('subscribed')]
#[Authorize('create', [Comment::class, 'post'])]
public function store(Post $post)
{
// Only authenticated, subscribed users who can create comments reach here
}
public function index(Post $post)
{
// Still requires auth (from class-level attribute)
return $post->comments;
}
}Het klasse-level #[Middleware('auth')] geldt voor alle methoden. Methode-level attributen worden gestapeld: store() vereist zowel auth als subscribed. Het #[Authorize]-attribuut integreert met Laravel's policy-systeem, en controleert rechten voor uitvoering van de methode.
Deze attribuut-gebaseerde aanpak is optioneel. Route-file middleware en bootstrap/app.php-registratie blijven volledig ondersteund. Teams die expliciete routedefinities prefereren kunnen de fluent API blijven gebruiken; teams die zelfdocumenterende controllers willen kunnen attributen adopteren.
Terminable Middleware voor Post-Response Taken
Terminable middleware voert logica uit na het verzenden van het antwoord naar de client. Dit is nuttig voor logging, analytics of opruimtaken die de gebruiker niet moeten blokkeren.
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use IlluminateSupportFacadesDB;
use SymfonyComponentHttpFoundationResponse;
class CollectAnalytics
{
public function handle(Request $request, Closure $next): Response
{
return $next($request); // Pass through without delay
}
public function terminate(Request $request, Response $response): void
{
// Runs after response is sent to client
DB::table('analytics')->insert([
'path' => $request->path(),
'method' => $request->method(),
'status_code' => $response->getStatusCode(),
'user_id' => $request->user()?->id,
'ip' => $request->ip(),
'created_at' => now(),
]);
}
}De terminate-methode ontvangt zowel het originele verzoek als het uiteindelijke antwoord. Registreer de middleware als singleton in AppServiceProvider om te verzekeren dat dezelfde instantie zowel handle() als terminate() afhandelt.
Praktische Middleware Patronen voor Productie
Verschillende middleware-patronen verschijnen consistent in productie Laravel-applicaties.
Onderhoudsmodus bypass staat interne IP's toe om de applicatie te benaderen tijdens onderhoud:
class MaintenanceBypass
{
private array $allowedIps = ['192.168.1.0/24', '10.0.0.1'];
public function handle(Request $request, Closure $next): Response
{
if (app()->isDownForMaintenance()) {
foreach ($this->allowedIps as $ip) {
if ($request->ip() === $ip) {
return $next($request);
}
}
}
return $next($request);
}
}Security headers voegen HSTS, content security policy en andere headers toe aan elk antwoord:
class SecurityHeaders
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set('X-Content-Type-Options', 'nosniff');
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
$response->headers->set(
'Strict-Transport-Security',
'max-age=31536000; includeSubDomains'
);
return $response;
}
}Deze patronen demonstreren de twee primaire middleware-posities: voor het verzoek (onderhoudsmodus bypass controleert het IP en blokkeert mogelijk) en na het antwoord (security headers wijzigen het uitgaande antwoord).
Klaar om je Laravel gesprekken te halen?
Oefen met onze interactieve simulatoren, flashcards en technische tests.
Bronnen
- Laravel Middleware Documentatie - Officiele referentie voor middleware-registratie, groepen en parameters
- Laravel 13 Release Notes - Aankondiging van het
#[Middleware]-attribuut enPreventRequestForgery-verbeteringen - Laravel Rate Limiting Documentatie - RateLimiter facade, benoemde limiters en throttle middleware-configuratie
Laravel Middleware Patronen voor Sollicitatiegesprek Voorbereiding
- Laravel middleware werkt als een pipeline: elke klasse verwerkt het verzoek, handelt erop en geeft het door of onderbreekt met een antwoord
- De
auth-middleware beschermt routes met guard-gebaseerde authenticatie, met ondersteuning voor meerdere gebruikerstypen viaauth:guard-syntax - Rate limiting via
throttle-middleware en benoemdeRateLimiter::for()-definities maakt gelaagde toegangscontrole mogelijk op basis van gebruikerscontext - Eigen middleware handelt cross-cutting concerns af zoals rolcontroles, request-sanitisatie en security headers zonder controllers te overladen
- Alle middleware-registratie gebeurt in
bootstrap/app.phpvia een fluent API, waarbijpriorityde uitvoeringsvolgorde bepaalt - Laravel 13's
#[Middleware]-attribuut maakt het declareren van middleware direct op controllers mogelijk, waardoor autorisatieregels naast handlers blijven - Terminable middleware voert post-response taken uit (analytics, logging) zonder impact op door gebruikers waargenomen latentie
- Middleware-parameters via de
:param-syntax houden routedefinities expressief en middleware-klassen herbruikbaar in verschillende contexten
Begin met oefenen!
Test je kennis met onze gespreksimulatoren en technische tests.
Zie jij de bug in Laravel?
Een echt codefragment, een verborgen bug, één poging per dag. Zonder account uit te proberen.

Geschreven door
Anthony Fillion-MailletOprichter van SharpSkill
Al meer dan 10 jaar fullstack-ontwikkelaar. Hij leidt SharpSkill en staat in voor alles wat hier verschijnt.
Bijgewerkt op 21 september 2026
Tags
Delen
Gerelateerde artikelen

Laravel 12 in 2026: Nieuwe Features, Starter Kits en Sollicitatievragen
Laravel 12 introduceert volledig vernieuwde Starter Kits met React 19, Vue 3, Livewire 4 en WorkOS AuthKit. Een complete gids over nieuwe features, het upgradepad en belangrijke sollicitatievragen voor 2026.

Laravel Oplossingen: Geavanceerde Patterns, Debugging en Sollicitatievragen 2026
Beheers Laravel-oplossingen met geavanceerde architectuurpatronen, debugging-technieken en sollicitatievoorbereiding. Service classes, repository pattern, debugging met Telescope en veelgestelde sollicitatievragen voor Laravel-ontwikkelaars.

Laravel Events en Listeners 2026: Event-Driven Architecture en Sollicitatievragen
Complete gids voor Laravel Events en Listeners in 2026. Event-Driven Architecture, Observer Pattern, Broadcasting en veelgestelde technische sollicitatievragen met codevoorbeelden.