aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Webentwicklung

Laravel Middleware: Was es ist und wie man es schreibt

Laravel Middleware ist eine Filterschicht, die ausgeführt wird, bevor eine HTTP-Anfrage die inneren Teile deiner Anwendung erreicht und bevor die Antwort zurück an den Browser geht. Stell sie dir als eine Reihe von Toren zwischen der Anfrage und deinem Controller vor: Jedes Tor prüft die Anfrage und kann sie stoppen, verändern oder an das nächste Tor weiterreichen. Fast alles wie Authentifizierung, Session-Verwaltung, CSRF-Schutz und Spracherkennung wird mit Middleware erledigt.

Die Rolle der Middleware in der Request/Response-Kette

In Laravel durchläuft jede eingehende Anfrage eine "Pipeline". Diese Pipeline funktioniert wie eine Zwiebel: Die Anfrage durchläuft jede Schicht von außen nach innen, bis sie den Controller erreicht, und die Antwort reist anschließend in umgekehrter Richtung durch dieselben Schichten wieder nach außen. Dadurch kann eine einzelne Middleware Code sowohl vor der Anfrage als auch nach der Antwort ausführen.

  • Code, der davor läuft: prüft die Anfrage, bevor sie den Controller erreicht (zum Beispiel: ist der Benutzer angemeldet?).
  • Code, der danach läuft: erledigt Arbeit, sobald die Antwort erzeugt wurde, etwa einen Header hinzufügen oder einen Logeintrag schreiben.

Die Reihenfolge in der Kette ist wichtig. Die Middleware, die die Session startet, muss zum Beispiel vor jeder Prüfung laufen, die von dieser Session abhängt. Laravel legt eine sinnvolle Standardreihenfolge fest, aber bei deiner eigenen Middleware musst du auf ihre Position im Stack achten.

Wie Middleware funktioniert: der grundlegende Aufbau

Jede Middleware ist eine einfache Klasse mit einer handle-Methode. Diese Methode erhält zwei Parameter: die eingehende $request und eine Closure namens $next. Der Aufruf von $next($request) reicht die Anfrage an das nächste Glied der Kette weiter.

public function handle(Request $request, Closure $next)
{
    // Logik vor der Anfrage

    $response = $next($request);

    // Logik nach der Antwort

    return $response;
}

Alles, was du vor der Zeile $next($request) schreibst, läuft, bevor die Anfrage den Controller erreicht; alles danach läuft, während die Antwort zurückreist. Wenn die Anfrage gar nicht weitergehen soll (zum Beispiel bei verweigertem Zugriff), gibst du einfach eine Antwort zurück, ohne $next aufzurufen.

Eigene Middleware schreiben

Der praktischste Weg, eine neue Middleware zu erstellen, ist der Artisan-Befehl:

php artisan make:middleware EnsureTokenIsValid

Das erzeugt die Datei app/Http/Middleware/EnsureTokenIsValid.php. Angenommen, wir wollen jede Anfrage ablehnen, die kein gültiges Token in einem bestimmten Header trägt:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureTokenIsValid
{
    public function handle(Request $request, Closure $next): Response
    {
        if ($request->header('X-Api-Token') !== config('services.api.token')) {
            abort(403, 'Ungültiges Token.');
        }

        return $next($request);
    }
}

Stimmt das Token nicht überein, unterbricht abort(403) die Kette sofort und die Anfrage erreicht nie einen Controller. Stimmt es überein, läuft der Ablauf mit $next($request) weiter.

Middleware registrieren (Laravel 11 und 12)

Seit Laravel 11 ist die Registrierung von Middleware aus der alten Datei app/Http/Kernel.php in bootstrap/app.php umgezogen. Es gibt drei Hauptwege:

  • Globale Middleware: auf jede Anfrage angewendet.
  • Gruppen-Middleware: Routengruppen wie web oder api hinzugefügt.
  • Middleware mit Alias: einzelnen Routen über ->middleware('alias') zugewiesen.
// bootstrap/app.php
return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware) {
        // Einen Alias für einzelne Routen definieren
        $middleware->alias([
            'token' => \App\Http\Middleware\EnsureTokenIsValid::class,
        ]);

        // Zur web-Gruppe hinzufügen
        $middleware->web(append: [
            \App\Http\Middleware\SetLocale::class,
        ]);
    })
    ->create();

Sobald der Alias definiert ist, verwendest du ihn auf Routen so:

Route::get('/dashboard', DashboardController::class)
    ->middleware('token');

Hinweis: Wenn du noch Laravel 10 oder älter verwendest, erfolgen dieselben Registrierungen in den Arrays $middlewareAliases und $middlewareGroups in app/Http/Kernel.php.

Middleware mit Parametern

Middleware kann auch zusätzliche Argumente annehmen. Die eingebauten Autorisierungs- und Rollenprüfungen von Laravel funktionieren genau nach diesem Prinzip. Du fügst der handle-Methode nach $next Parameter hinzu:

public function handle(Request $request, Closure $next, string $role): Response
{
    if (! $request->user()?->hasRole($role)) {
        abort(403);
    }

    return $next($request);
}

Auf der Route übergibst du den Wert nach einem Doppelpunkt:

Route::get('/admin', AdminController::class)
    ->middleware('role:editor');

Häufige Fehler

  • Vergessen, $next($request) zurückzugeben: Gibt die Methode keine Antwort zurück, erhältst du eine leere Seite oder einen Fehler. Sofern du nicht vorzeitig abbrichst, schreibe immer return $next($request).
  • Falsche Reihenfolge: Läuft sessionabhängige Arbeit vor der Session-Middleware, kommt es zu unerwarteten Ergebnissen.
  • Zu viel Last: Middleware läuft bei jeder Anfrage; setze Datenbankabfragen und externe API-Aufrufe hier sparsam ein und cache sie, wo möglich.

Häufige Fragen

Was ist der Unterschied zwischen Middleware und einem Controller?

Ein Controller führt die eigentliche Geschäftslogik einer bestimmten Route aus. Middleware ist eine querschnittliche Schicht, die allgemeine Filterung oder Prüfungen auf die Anfrage anwendet und sich über viele Routen wiederholt. Aufgaben wie Authentifizierung gehören in die Middleware, nicht in den Controller.

Kann ich einer Route mehrere Middlewares hinzufügen?

Ja. Du übergibst ein Array wie ->middleware(['auth', 'token', 'role:editor']); sie werden in der Reihenfolge, in der du sie schreibst, zur Kette hinzugefügt.

Kann ich globale Middleware von bestimmten Routen ausschließen?

Meist ist die sauberere Lösung, die Middleware über einen Alias der betreffenden Gruppe oder den Routen hinzuzufügen, statt sie global zu machen. So steuerst du genau, wo sie läuft.

Möchtest du die Middleware-Architektur in deinem Laravel-Projekt richtig aufsetzen? Von der Authentifizierung bis zur mehrsprachigen Erkennung helfe ich dir, eine saubere, testbare Middleware-Schicht zu entwerfen. Nimm Kontakt mit mir auf.

Devamı için