wake-up-neo.net

Ausführungsreihenfolge der Middleware in Laravel 5

Die Laravel 5-Dokumentation beschreibt zwei Arten der Zuweisung von Middleware :

  1. Weisen Sie der Route des Controllers Middleware zu.
  2. Legen Sie die Middleware im Konstruktor Ihres Controllers fest.

Ich habe jedoch festgestellt, dass jeder Code, der in die __construct()-Funktion der Controller geschrieben wurde, vor der Middleware ausgeführt wird, auch wenn die Middleware in der ersten Zeile der __construct-Funktion der Controller deklariert ist.

Ich habe einen Fehlerbericht für ein ähnliches Problem im Laravel Github-Repository gefunden. Ein Mitarbeiter schloss das Problem jedoch mit dem Hinweis "Dies ist das erwartete Verhalten.".

Ich frage mich, dass middleware "Schichten" außerhalb der Anwendung sein sollte, während die __construct-Funktion Teil der Anwendung ist. Warum wird die __construct-Funktion vor der Middleware ausgeführt (vorausgesetzt es handelt sich um eine Middleware), und warum wird dies erwartet?

17
Samuel Shen

Die Anwendungslogik befindet sich in den Methoden des Controllers. Die Anwendung lebt also grundsätzlich in den Methoden des Controllers, nicht im gesamten Controller selbst. 

Die Middleware wird ausgeführt, BEVOR die Anforderung in die jeweilige Controller-Methode eingegeben wird. Und so ist dies immer AUSSERHALB der realen Anwendung. Es wird keine Controller-Methode ausgeführt, es sei denn, alle Middlewares übermitteln die Anforderung.

Die $this->middleware("My\Middleware");-Anweisungen, die Sie in den Controller-Konstruktor einfügen, REGISTERS den My\Middleware zur Überprüfung, bevor die Anforderung in die Anwendung eingeht. 

Wenn Sie den Code einer Middleware und Sehen, wenn die Anforderung übergeben wird, senden Sie ihn mit der $next($request);-Anweisung an die nächste Middleware. Dadurch können mehrere Middlewares für eine einzelne Anfrage ausgeführt werden. Wenn nun Laravel die Middleware direkt bei der $this->middleware(...);-Anweisung ausführt, könnte Laravel wahrscheinlich nicht wissen, welche Middleware als nächstes überprüft werden sollte.

Daher löst Laravel dies, indem zuerst alle Middlewares registriert werden und dann die Anforderung nacheinander durch alle Middlewares geleitet wird.

9
Curos

Eine weitere Antwort auf einen anderen Anwendungsfall dieser Frage

Wenn es sich um die Reihenfolge zwischen Middleware handelt, ist es von selbst

Sie können $ MiddlewarePriority in Ihrem App\Kernel aktualisieren.

3
Bdwey

Sie haben die Ausführungsreihenfolge zwischen middlewares, controller und dem Konstrukt des Controllers aktualisiert.

Bisher war es:

1. The global middleware pipeline
2. The route middleware pipeline
3. The controller middleware pipeline

Jetzt ist es:

1. The global middleware pipeline
2. Controller's Construct
3. The route & controller middlewares

Lesen Sie hier mehr: https://laracasts.com/discuss/channels/general-discussion/execution-order-in-controller-constructor-whit-middlewarehttps : //laravel-news.com/controller-construct-session-changes-in-laravel-5-3

2
Raheel Hasan

Setzen Sie die Middleware-Priorität in App\Http\Kernel

Hier muss zum Beispiel meine benutzerdefinierte Authentifizierungs-Middleware zuerst ausgeführt werden (bevor die Bindungen ersetzt werden), damit ich sie auf den Stapel verschiebe:

public function __construct(Application $app, Router $router)
{
    /**
     * Because we are using a custom authentication middleware,
     * we want to ensure it's executed early in the stack.
     */
    array_unshift($this->middlewarePriority, MyCustomApiAuthMiddleware::class);

    parent::__construct($app, $router);
}

Alternativ können Sie die gesamte Prioritätsstruktur überschreiben, wenn Sie eine explizite Steuerung benötigen (nicht empfohlen, da Sie bei Upgrades genauer darauf achten müssen, ob sich das Framework ändert). Speziell für dieses Problem ist die Klasse SubstituteBindings, die die Routenmodellbindung verarbeitet. Stellen Sie daher sicher, dass Ihre Authentifizierungs-Middleware irgendwann vorher installiert wurde.

/**
 * The priority-sorted list of middleware.
 *
 * Forces the listed middleware to always be in the given order.
 *
 * @var array
 */
protected $middlewarePriority = [
    \App\Http\Middleware\MyCustomApiAuthMiddleware::class
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \Illuminate\Auth\Middleware\Authenticate::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];
1
Jeff Puckett