# Laravel Middleware im Detail: Authentifizierung, Rate Limiting und eigene Middleware > Umfassender Leitfaden zu Laravel Middleware mit praktischen Beispielen zu Authentifizierung, Rate Limiting, eigener Middleware-Erstellung und fortgeschrittenen Produktionsmustern. - Published: 2026-04-16 - Updated: 2026-04-16 - Author: SharpSkill - Tags: laravel, middleware, authentifizierung, rate-limiting, php - Reading time: 10 min --- Middleware bildet das Fundament jeder robusten Laravel-Anwendung. Sie steht als unsichtbare Filterschicht zwischen eingehenden HTTP-Requests und der Anwendungslogik, prueft Zugriffsrechte, begrenzt die Anfragehaeufigkeit und transformiert Daten -- noch bevor ein Controller eine einzige Zeile Code ausfuehrt. Ob Authentifizierung, Rate Limiting oder massgeschneiderte Prueflogik: Wer Laravel produktionsreif einsetzen will, muss die Middleware-Pipeline im Detail verstehen. Dieser Artikel zeigt anhand konkreter Codebeispiele, wie die Middleware-Pipeline funktioniert, welche eingebauten Middleware-Klassen Laravel mitbringt und wie eigene Middleware fuer spezifische Anforderungen erstellt wird. > **Warum Middleware unverzichtbar ist** > > Middleware entkoppelt wiederkehrende Querschnittsbelange wie Authentifizierung, Logging und Eingabevalidierung von der eigentlichen Geschaeftslogik. Statt Sicherheitspruefungen in jedem Controller zu wiederholen, werden sie zentral in der Middleware definiert und automatisch auf alle relevanten Routen angewendet. Das Ergebnis: schlanke Controller, konsistente Sicherheitsmechanismen und eine Codebasis, die sich einfach warten laesst. ## So funktioniert die Middleware-Pipeline Die Middleware-Pipeline in Laravel laesst sich am besten als eine Reihe konzentrischer Schichten vorstellen. Jeder HTTP-Request durchlaeuft diese Schichten von aussen nach innen, bis er den Controller erreicht. Die Response durchlaeuft anschliessend dieselben Schichten in umgekehrter Reihenfolge. Dieses Prinzip wird besonders deutlich, wenn man eine Middleware betrachtet, die sowohl vor als auch nach der Controller-Verarbeitung Code ausfuehrt. Das folgende Beispiel misst die Verarbeitungszeit eines Requests. Der Code vor dem Aufruf von `$next($request)` wird ausgefuehrt, bevor der Request den Controller erreicht. Der Code danach wird ausgefuehrt, nachdem die Response erzeugt wurde -- ein klassisches Beispiel fuer die Zwiebelschalen-Architektur der Pipeline. ```php // app/Http/Middleware/LogRequestTime.php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; use Symfony\Component\HttpFoundation\Response; 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 } } ``` Der Schluessel liegt in `$next($request)`: Dieser Aufruf uebergibt den Request an die naechste Middleware in der Kette. Alles vor diesem Aufruf ist Before-Middleware-Logik, alles danach ist After-Middleware-Logik. Wird `$next()` nie aufgerufen -- beispielsweise weil eine Authentifizierungspruefung fehlschlaegt -- gelangt der Request gar nicht erst zum Controller. ## Authentication Middleware Die Authentifizierung ist der haeufigste Anwendungsfall fuer Middleware in Laravel. Die eingebaute `auth`-Middleware stellt sicher, dass nur angemeldete Benutzer auf geschuetzte Routen zugreifen koennen. Nicht authentifizierte Benutzer werden automatisch zur Login-Seite umgeleitet oder erhalten eine 401-Response bei API-Requests. Routen lassen sich einzeln oder in Gruppen schuetzen. Die Gruppierung ist dabei die bevorzugte Methode, da sie die Routendefinitionen uebersichtlich haelt und sicherstellt, dass keine Route versehentlich ungeschuetzt bleibt. ```php // routes/web.php use App\Http\Controllers\DashboardController; use App\Http\Controllers\ProfileController; // 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-Authentifizierung Laravel unterstuetzt mehrere Authentication Guards, die parallel eingesetzt werden koennen. Ein Guard definiert, wie Benutzer authentifiziert werden -- ob ueber Sessions, API-Tokens oder benutzerdefinierte Mechanismen. Durch Angabe des Guard-Namens nach dem Doppelpunkt laesst sich steuern, welcher Authentifizierungsmechanismus fuer eine bestimmte Routengruppe verwendet wird. ```php // routes/api.php // 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']); }); ``` Diese Trennung ermoeglicht es, API-Routen mit Sanctum-Tokens und Admin-Routen mit einem separaten Guard abzusichern. Jeder Guard kann eigene Benutzermodelle, Provider und Treiber verwenden, was eine flexible Architektur fuer komplexe Anwendungen schafft. > **Die guest-Middleware** > > Neben der `auth`-Middleware existiert die `guest`-Middleware, die das umgekehrte Verhalten implementiert: Sie laesst nur nicht-authentifizierte Benutzer durch. Typische Anwendungsfaelle sind Login- und Registrierungsseiten, die authentifizierte Benutzer automatisch zum Dashboard weiterleiten sollen. Die Verwendung erfolgt identisch: `Route::middleware('guest')->get('/login', ...)`. ## Rate Limiting mit Throttle Rate Limiting schuetzt Anwendungen vor Missbrauch, Brute-Force-Angriffen und unbeabsichtigter Ueberlastung. Die `throttle`-Middleware in Laravel begrenzt die Anzahl der Requests, die ein Client innerhalb eines definierten Zeitfensters senden darf. Wird das Limit ueberschritten, antwortet Laravel automatisch mit dem HTTP-Statuscode 429 (Too Many Requests). Die einfachste Form der Konfiguration erfolgt direkt in der Routendefinition. Der erste Parameter gibt die maximale Anzahl der Requests an, der zweite das Zeitfenster in Minuten. ```php // routes/api.php // 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']); }); ``` Diese grundlegende Konfiguration reicht fuer einfache Anwendungsfaelle aus. Fuer differenziertere Anforderungen -- etwa unterschiedliche Limits fuer verschiedene Benutzergruppen -- bietet Laravel benannte Rate Limiters an. ### Benannte Rate Limiters Benannte Rate Limiters werden in einem Service Provider definiert und ermoeglichen dynamische, kontextabhaengige Konfigurationen. Das folgende Beispiel zeigt ein gestaffeltes System: Enterprise-Kunden erhalten grosszuegigere Limits als regulaere Benutzer, waehrend anonyme Zugriffe am staerksten eingeschraenkt werden. ```php // app/Providers/AppServiceProvider.php use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Support\Facades\RateLimiter; use Illuminate\Http\Request; 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); }); }); } ``` Die benannten Limiter werden anschliessend ueber ihren Namen in der Routendefinition referenziert, anstatt die numerischen Werte direkt anzugeben. ```php // routes/api.php Route::middleware('throttle:api')->group(function () { Route::apiResource('/posts', PostController::class); }); // routes/web.php Route::middleware('throttle:login') ->post('/login', [AuthController::class, 'login']); ``` Der Vorteil dieses Ansatzes liegt in der zentralen Konfiguration: Werden die Limits angepasst, aendert sich automatisch das Verhalten aller Routen, die den entsprechenden Limiter verwenden. Die `by()`-Methode steuert dabei, wie Requests gruppiert werden -- ob nach Benutzer-ID, IP-Adresse oder einer beliebigen Kombination. ## Eigene Middleware erstellen Wenn die eingebauten Middleware-Klassen nicht ausreichen, lassen sich mit einem einzigen Artisan-Befehl neue Middleware-Klassen generieren. ```bash php artisan make:middleware EnsureUserHasRole ``` Dieser Befehl erstellt eine Klasse im Verzeichnis `app/Http/Middleware/` mit einer vorbereiteten `handle`-Methode. Anschliessend kann die gewuenschte Logik implementiert werden. ### Rollenbasierte Zugriffskontrolle Ein typischer Anwendungsfall fuer Custom Middleware ist die rollenbasierte Autorisierung. Die folgende Middleware prueft, ob der authentifizierte Benutzer eine der erforderlichen Rollen besitzt. Durch den Spread-Operator (`...$roles`) unterstuetzt sie eine variable Anzahl von Rollen als Parameter. ```php // app/Http/Middleware/EnsureUserHasRole.php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; 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); } } ``` Die Registrierung erfolgt als Alias in `bootstrap/app.php`, sodass die Middleware in Routendefinitionen ueber einen kurzen, sprechenden Namen verwendet werden kann. Parameter werden nach dem Doppelpunkt uebergeben, mehrere durch Komma getrennt. ```php // bootstrap/app.php ->withMiddleware(function (Middleware $middleware) { $middleware->alias([ 'role' => \App\Http\Middleware\EnsureUserHasRole::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-Sanitierung fuer APIs Ein weiterer gaengiger Anwendungsfall ist die Validierung und Bereinigung eingehender API-Requests. Die folgende Middleware stellt sicher, dass POST-Requests den korrekten Content-Type verwenden und bereinigt alle String-Eingaben durch Entfernung ueberfluessiger Leerzeichen. ```php // app/Http/Middleware/ApiRequestSanitizer.php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; 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); } } ``` Diese Middleware wird idealerweise am Anfang der API-Middleware-Gruppe eingefuegt, sodass alle nachfolgenden Middleware-Klassen und Controller bereits bereinigte Daten erhalten. ## Middleware-Registrierung in Laravel 12 Seit Laravel 11 hat sich die Middleware-Konfiguration grundlegend veraendert. Statt des frueheren `App\Http\Kernel` erfolgt die gesamte Registrierung in `bootstrap/app.php`. Dort lassen sich globale Middleware, Gruppen-Middleware, Aliase und die Ausfuehrungsprioritaet zentral definieren. ```php // bootstrap/app.php use Illuminate\Foundation\Application; use Illuminate\Foundation\Configuration\Middleware; return Application::configure(basePath: dirname(__DIR__)) ->withMiddleware(function (Middleware $middleware) { // Global middleware (runs on every request) $middleware->append( \App\Http\Middleware\LogRequestTime::class ); // Add to the 'web' middleware group $middleware->web(append: [ \App\Http\Middleware\TrackPageViews::class, ]); // Add to the 'api' middleware group $middleware->api(prepend: [ \App\Http\Middleware\ApiRequestSanitizer::class, ]); // Register aliases for route-level use $middleware->alias([ 'role' => \App\Http\Middleware\EnsureUserHasRole::class, 'subscribed' => \App\Http\Middleware\EnsureUserIsSubscribed::class, ]); // Control execution order $middleware->priority([ \Illuminate\Session\Middleware\StartSession::class, \Illuminate\Auth\Middleware\Authenticate::class, \App\Http\Middleware\EnsureUserHasRole::class, ]); }) ->create(); ``` Die Methoden `append()` und `prepend()` steuern, ob eine Middleware am Ende oder am Anfang einer Gruppe eingefuegt wird. Globale Middleware (`$middleware->append(...)` ohne Gruppenangabe) wird bei jedem Request ausgefuehrt -- unabhaengig davon, ob es sich um eine Web- oder API-Route handelt. > **Ausfuehrungsreihenfolge beachten** > > Die Reihenfolge der Middleware-Ausfuehrung ist entscheidend. Die Session muss gestartet sein, bevor die Authentifizierung geprueft werden kann. Die Authentifizierung muss vor der Autorisierung erfolgen. Rate Limiting sollte vor rechenintensiver Geschaeftslogik greifen. Die `priority()`-Methode erzwingt diese Reihenfolge global, unabhaengig davon, in welcher Reihenfolge die Middleware auf einer Route definiert wurde. ## Terminable Middleware Nicht alle Aufgaben muessen abgeschlossen sein, bevor die Response an den Client gesendet wird. Terminable Middleware implementiert eine zusaetzliche `terminate()`-Methode, die erst nach dem vollstaendigen Senden der Response ausgefuehrt wird. Der Client erhaelt die Antwort also schneller, waehrend die Anwendung im Hintergrund weitere Verarbeitung vornimmt. ```php // app/Http/Middleware/CollectAnalytics.php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Symfony\Component\HttpFoundation\Response; 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(), ]); } } ``` Typische Anwendungsfaelle fuer Terminable Middleware sind Analytics-Erfassung, Audit-Logging, Cache-Aufwaermung und das Versenden von Benachrichtigungen. Wichtig zu beachten: Laravel erstellt fuer die `terminate()`-Methode eine neue Instanz der Middleware, sofern die Middleware nicht als Singleton im Container registriert ist. Bei zustandsbehafteter Verarbeitung muss dies beruecksichtigt werden. ## Produktionsmuster In Produktionsumgebungen werden haeufig wiederkehrende Middleware-Muster eingesetzt, die ueber die Standardfaelle hinausgehen. Zwei besonders nuetzliche Beispiele sind die Wartungsmodus-Umgehung und das Setzen von Sicherheits-Headern. ### Wartungsmodus-Umgehung Waehrend des Wartungsmodus sollen Entwickler und Administratoren weiterhin auf die Anwendung zugreifen koennen, um Aenderungen zu ueberpruefen. Die folgende Middleware erlaubt den Zugriff von bestimmten IP-Adressen, waehrend alle anderen Besucher die Wartungsseite sehen. ```php // app/Http/Middleware/MaintenanceBypass.php 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); } } ``` ### Sicherheits-Header HTTP-Sicherheits-Header sind ein wesentlicher Bestandteil jeder Produktionsanwendung. Statt sie in der Webserver-Konfiguration zu setzen, koennen sie direkt in einer Middleware definiert werden -- das erleichtert die Versionierung und sorgt dafuer, dass die Header unabhaengig vom verwendeten Webserver gesetzt werden. ```php // app/Http/Middleware/SecurityHeaders.php 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; } } ``` Beide Middleware-Klassen eignen sich hervorragend als globale Middleware, da sie auf jeden Request angewendet werden sollen. Die Sicherheits-Header-Middleware ist dabei ein Beispiel fuer After-Middleware, da sie die Response nach der Controller-Verarbeitung modifiziert. ## Zusammenfassung Laravel Middleware ist weit mehr als eine einfache Filterschicht. Sie bildet das Rueckgrat der Request-Verarbeitung und ermoeglicht eine saubere Architektur, in der Sicherheits- und Infrastrukturbelange von der Geschaeftslogik getrennt sind. Die wichtigsten Erkenntnisse im Ueberblick: - **Pipeline-Architektur**: Jeder Request durchlaeuft eine Kette von Middleware-Klassen. Die Position des Codes relativ zu `$next($request)` bestimmt, ob Logik vor oder nach der Controller-Verarbeitung ausgefuehrt wird. - **Authentication Middleware**: Die `auth`-Middleware schuetzt Routen vor unauthentifizierten Zugriffen. Multi-Guard-Konfigurationen ermoeglichen separate Authentifizierungsmechanismen fuer Web, API und Admin-Bereiche. - **Rate Limiting**: Die `throttle`-Middleware und benannte Rate Limiters bieten flexible Konfigurationsmoeglichkeiten von einfachen Begrenzungen bis hin zu gestaffelten, rollenbasierten Systemen. - **Custom Middleware**: Mit `php artisan make:middleware` lassen sich in Sekunden neue Middleware-Klassen erstellen. Parameter, der Spread-Operator und Aliase ermoeglichen wiederverwendbare, konfigurierbare Middleware. - **Registrierung in bootstrap/app.php**: Seit Laravel 11 erfolgt die gesamte Middleware-Konfiguration zentral in einer einzigen Datei, einschliesslich globaler Middleware, Gruppen, Aliase und Prioritaeten. - **Terminable Middleware**: Die `terminate()`-Methode ermoeglicht nicht-blockierende Nachverarbeitung nach dem Senden der Response, ideal fuer Analytics und Audit-Logging. - **Produktionsmuster**: Wartungsmodus-Umgehung und Sicherheits-Header sind typische Beispiele fuer Middleware, die in jeder produktionsreifen Laravel-Anwendung vorhanden sein sollte. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/de/blog/laravel/laravel-middleware-deep-dive