Middleware
Einführung
Middleware bietet einen praktischen Mechanismus zum Filtern von HTTP-Anfragen, die in eine Anwendung eingehen. Laravel enthält beispielsweise eine Middleware, die die Benutzerauthentifizierung für Ihre Anwendung überprüft. Wenn der Benutzer nicht authentifiziert ist, leitet die Middleware den Benutzer zur Anmeldeschnittstelle weiter. Wenn der Benutzer jedoch authentifiziert ist, lässt die Middleware die Anfrage an die Anwendung weiterhin zu.
Natürlich kann zusätzlich zur Identitätsauthentifizierung auch zusätzliche Middleware geschrieben werden, um verschiedene Aufgaben auszuführen. Beispielsweise kann die CORS-Middleware für das Hinzufügen geeigneter Header-Informationen zu allen Antworten verantwortlich sein, die die Anwendung verlassen. Die Protokollierungs-Middleware kann alle in der Anwendung eingehenden Anforderungen protokollieren.
Laravel wird mit einiger Middleware geliefert, einschließlich Authentifizierung, CSRF-Schutz usw. Alle diese Middlewares befinden sich im Verzeichnis app/Http/Middleware
.
Middleware definieren
Erstellen Sie eine neue Middleware, indem Sie den make:middleware
Artisan-Befehl ausführen:
php artisan make:middleware CheckAge
Dieser Befehl erstellt ein neues Verzeichnis im Verzeichnis app/Http/Middleware
CheckAge
Klasse, in dieser Middleware erlauben wir nur Anfragen mit age
Parametern größer als 200
, auf diese Route zuzugreifen, andernfalls wird sie zu home
<?php namespace App\Http\Middleware; use Closure;class CheckAge{ /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if ($request->age <= 200) { return redirect('home'); } return $next($request); } }
umgeleitet, wie Sie sehen können. Wenn der angegebene age
-Parameter kleiner oder gleich 200
ist, gibt diese Middleware ein HTTP zurück Weiterleitung an den Client; andernfalls wird die Anfrage weiter an die Anwendung weitergeleitet. Damit die Anfrage an die Anwendung weitergeleitet werden kann (d. h. damit die Middleware die Validierung „bestehen“ kann), rufen Sie einfach die Rückruffunktion $request
mit $next
als Parameter auf.
Stellen Sie sich Middleware am besten als eine Reihe von HTTP
Anfragen vor, die durchlaufen werden müssen, um zur „Schicht“ Ihrer Anwendung zu gelangen. Jede Ebene prüft die Anfrage (ob sie bestimmte Bedingungen erfüllt) und kann sie sogar vollständig ablehnen (falls dies nicht der Fall ist) (bevor sie Zugriff auf Ihre Anwendung anfordert).
{Tipp} Die gesamte Middleware wird durch den Service-Container geleitet, sodass alle benötigten Abhängigkeiten in den Konstruktor Ihrer Middleware eingegeben werden können.
Pre & Post Middleware
Middleware wird je nach Middleware selbst vor oder nach der Anfrage ausgeführt. Beispielsweise führt die folgende Middleware eine Aufgabe aus, bevor die Anwendung die Anfrage verarbeitet :
<?php namespace App\Http\Middleware; use Closure;class BeforeMiddleware{ public function handle($request, Closure $next) { // Perform action return $next($request); } }
Diese Middleware wird jedoch vor der Anwendung verarbeitet Danach führen Sie einige Aufgaben aus:
<?php namespace App\Http\Middleware; use Closure; class AfterMiddleware{ public function handle($request, Closure $next) { $response = $next($request); // Perform action return $response; } }
Middleware registrieren
Globale Middleware
Wenn Sie möchten, dass die Middleware alles verwaltet Wird während einer HTTP-Anfrage ausgeführt. Listen Sie diese Middleware einfach im Attribut app/Http/Kernel.php
in $middleware
Middleware Routen zuweisen
Angenommen, Sie möchten einer bestimmten Route Middleware zuweisen. Zuerst sollten Sie der Middleware in der app/Http/Kernel.php
-Datei einen Schlüssel zuweisen. Standardmäßig ist die integrierte Middleware von Laravel unter dem Attribut $routeMiddleware
in dieser Klasse enthalten. Um eine benutzerdefinierte Middleware hinzuzufügen, hängen Sie sie einfach an die Liste an und weisen Sie ihr einen benutzerdefinierten Schlüssel zu. Zum Beispiel:
// 在 App\Http\Kernel 类中... protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, ];
Sobald die Middleware im HTTP-Kern definiert ist, kann sie übergeben werden middleware
Die Methode weist der Route Middleware zu:
Route::get('admin/profile', function () { // })->middleware('auth');
Sie können der Route auch mehrere Middleware zuweisen:
Route::get('/', function () { // })->middleware('first', 'second');
Beim Zuweisen von Middleware können Sie auch den vollständigen Klassennamen übergeben:
use App\Http\Middleware\CheckAge; Route::get('admin/profile', function () { // })->middleware(CheckAge::class);
Mittelkomponente
Manchmal möchten Sie möglicherweise einen Schlüssel verwenden, um mehrere Middleware aus Bequemlichkeitsgründen in einer Gruppe zu packen. Anwenden auf Routenführung. Sie können das HTTP-Kern-Attribut $middlewareGroups
verwenden.
Laravel verfügt über integrierte web
- und api
-Middleware-Gruppen, die gängige Middleware enthalten, die Sie möglicherweise auf Web-UI und API-Routing anwenden möchten:
/** * 应用程序的路由中间件组 * * @var array */ protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ ' throttle:60,1', 'auth:api',], ];
Middle Komponenten können Routen- und Controller-Aktionen mit derselben Syntax wie einzelne Middleware zugewiesen werden. Ebenso erleichtert Middleware das gleichzeitige Zuweisen mehrerer Middlewares zu einer Route:
Route::get('/', function () { // })->middleware('web'); Route::group(['middleware' => ['web']], function () { // });
{Tip}
RouteServiceProvider
Die Middleware-Gruppeweb
wird standardmäßig automatisch aufroutes/web.php
angewendet.
Middleware sortieren
In seltenen Fällen benötigen Sie möglicherweise Middleware, um sie in einer bestimmten Reihenfolge auszuführen. Sie haben jedoch keine Kontrolle über deren Reihenfolge, wenn sie Routen zugewiesen werden. In diesem Fall können Sie die Middleware-Priorität mithilfe des app/Http/Kernel.php
-Attributs der $middlewarePriority
-Datei angeben:
/** * 中间件的优先级排序列表 * * 将会强制非全局中间件始终保持给定的顺序。 * * @var array */ protected $middlewarePriority = [ \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\Authenticate::class, \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class,];
Middleware-Parameter
Middleware kann auch andere Parameter empfangen. Wenn Ihre Anwendung beispielsweise überprüfen muss, ob der Benutzer eine bestimmte „Rolle“ hat, bevor sie eine bestimmte Aktion ausführt, können Sie eine CheckRole
-Middleware erstellen, die den „Rollen“-Namen als zusätzlichen Parameter erhält.
Zusätzliche Zwischenparameter sollten nach den $next
-Parametern an die Middleware übergeben werden:
<?php namespace App\Http\Middleware; use Closure;class CheckRole{ /** * 处理传入的参数 * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string $role * @return mixed */ public function handle($request, Closure $next, $role) { if (! $request->user()->hasRole($role)) { // Redirect... } return $next($request); } }
Geben Sie beim Definieren einer Route die Middleware-Parameter an, indem Sie den Middleware-Namen und die Parameter durch ein :
trennen . Verwenden Sie Kommas, um mehrere Parameter zu trennen:
Route::put('post/{id}', function ($id) { // })->middleware('role:editor');
Terminierbare Middleware
Manchmal muss eine Middleware nach der Vorbereitung der HTTP-Antwort einige Arbeiten erledigen. Beispielsweise schreibt die integrierte „Session“-Middleware von Laravel Sitzungsdaten in den Speicher, wenn die Antwort vollständig bereit ist. Wenn Sie in Ihrer Middleware eine terminate
-Methode definieren, wird diese automatisch aufgerufen, nachdem die Antwort zum Senden an den Browser bereit ist. Die Methode
<?php namespace Illuminate\Session\Middleware; use Closure; class StartSession{ public function handle($request, Closure $next) { return $next($request); } public function terminate($request, $response) { // Store the session data... } }
terminate
sollte sowohl eine Anfrage als auch eine Antwort empfangen. Nachdem Sie diese Middleware definiert haben, vergessen Sie nicht, sie der Routenliste oder der globalen Middleware in der Datei app/Http/Kernel.php
hinzuzufügen.
Wenn Sie die terminate
-Methode für Middleware aufrufen, löst Laravel eine neue Middleware-Instanz aus dem Service-Container auf. Wenn Sie beim Aufrufen der Methoden handle
und terminate
dieselbe Middleware-Instanz verwenden, verwenden Sie die Methode singleton
des Containers, um die Middleware im Container zu registrieren.