web-dev-qa-db-ja.com

Laravelミドルウェアの実行順序を設定する方法は?

Laravel 5ドキュメント は、ミドルウェアを割り当てる2つの方法を説明しています。

  1. ミドルウェアをコントローラーのルートに割り当てます。
  2. コントローラーのコンストラクター内でミドルウェアを指定します。

ただし、コントローラー__construct()関数で記述されたすべてのコードは、ミドルウェアの前に実行されます(ミドルウェアは、コントローラの__construct関数の最初の行で宣言されています。

Laravel githubレポジトリで同様の問題の バグレポート を見つけました。しかし、共同作業者が「これは予期された動作です」と述べて問題を閉じました。

middlewareはアプリケーションの外部の「レイヤー」である必要があると考えていますが、__construct関数はアプリケーションの一部です。

__construct関数がミドルウェアの前に実行されるのはなぜですか(ミドルウェアの実行前に宣言されている場合)?なぜこれが予想されるのですか?

18
Samuel Shen

アプリケーションロジックは、コントローラーのメソッドに存在します。したがって、基本的にアプリケーションは、コントローラー全体ではなく、コントローラーのメソッド内に存在します。

ミドルウェアは、リクエストがそれぞれのコントローラーメソッドに入る前に実行されます。したがって、これは常に実際のアプリケーションの外側にあります。すべてのミドルウェアがリクエストを渡さない限り、コントローラメソッドは実行されません。

コントローラーコンストラクターに配置する$this->middleware("My\Middleware");ステートメントは、リクエストがアプリケーションに入る前にチェックするために_My\Middleware_を登録します。

ミドルウェアのコードが表示され、リクエストが通過している場合は、$next($request);ステートメントを使用して次のミドルウェアに送信します。これにより、単一のリクエストに対して複数のミドルウェアを実行できます。ここで、Laravel $this->middleware(...);ステートメントでミドルウェアを実行すると、Laravelは次のミドルウェアを認識できない可能性があります。チェックしました。

したがって、Laravelは、最初にすべてのミドルウェアを登録し、次にすべてのミドルウェアに1つずつリクエストを渡すことでこれを解決します。

9
Curos

その質問の別のユースケースをカバーするための別の答え

ミドルウェア間の注文に関連する場合

App\Kernelの$ middlewarePriorityを更新できます。

7
Bdwey

彼らは、middlewarescontrollerとコントローラーの構造の間の実行順序を更新しました。

以前は:

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

今その:

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

詳細はこちら: https://laracasts.com/discuss/channels/general-discussion/execution-order-in-controllers-constructor-whit-middlewarehttps:// laravel- news.com/controller-construct-session-changes-in-laravel-5-

2
Raheel Hasan

App\Http\Kernelでミドルウェアの優先度を設定する

たとえば、ここでは最初に(代替バインディングの前に)カスタム認証ミドルウェアを実行する必要があるため、スタックにシフトします。

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);
}

または、明示的な制御が必要な場合は、優先度構造全体をオーバーライドできます(フレームワークが変更されるかどうかを確認するためにアップグレード中に注意を払う必要があるため、推奨されません)。この問題に固有なのは、ルートモデルバインディングを処理するSubstituteBindingsクラスです。そのため、認証ミドルウェアがその前に来ることを確認してください。

/**
 * 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,
];
2
Jeff Puckett