多分依存関係の追加とかでいつも通りcomposer update
していたのであろう。知らないうちにlaravel-corsが部分的に使えなくなっていた。
特定のミドルウェアが場合によって動いてなさ気
それも質が悪いことに401の認可エラーのリソースのみがこの対象になっていたため発見が遅れてしまった。(まあ全てのリソースが使えなくなるのも最悪なんだけれど)
どうやらcorsミドルウェアが処理される前にauthミドルウェアがリクエストの処理を切り上げていたらしい。
挙動がおかしいことに気付き原因を探ろうとしてみたものの、laravel-cors
はしばらく大幅な更新がされた模様もそれらしいissueも見当たらない。(以前は問題なかったはずだった。)
ところで、本番では問題が発生しているのにローカルの開発環境ではこの問題が起こっていなくてそれはそれでまた首を傾げた。
よくみてみると、laravel/framework
は3日前に更新されていたが、ローカルはまだ5.3.18のままだった。
ローカルも更新をかけてみると、同様の問題が発生することが確認できた。
原因は……SortedMiddleware?
色々と試してみてこのアップデートが原因であるらしい、ということは確認できた。
そこでdiffでミドルウェア周りの変更を重点的に漁ったところ、ミドルウェアのソートが大幅に変更されてい、SortedMiddlewareなんていう拡張Collectionまで登場していた。
そのほかにミドルウェアの変更っぽいのは見当たらない。
とりあえずソート順位を変えてみるぞ……
テストを見た感じ、ミドルウェアのソートは明示的に指定されたものに限りその指定順にソートされるようになっているらしい。
この優先度は\Illuminate\Foundation\Http\Kernel::$middlewarePriority
において
1 2 3 4 5 6 7 |
protected $middlewarePriority = [ \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\Auth\Middleware\Authenticate::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class, ]; |
のように定義されている。
では、ここにCORSミドルウェアをAuthミドルウェアより上に追加すればいいはず。
\App\Http\Kernel
にオーバーライドを書いた。
1 2 3 4 5 6 7 8 |
protected $middlewarePriority = [ \Illuminate\Session\Middleware\StartSession::class, \Barryvdh\Cors\HandleCors::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\Auth\Middleware\Authenticate::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class, ]; |
これで、無事認可エラー時もCORSヘッダーが返ってくるようになった。
ところで、LaravelでMiddlewareの実行順序を設定する | takayukii.blogにパラメーター問題について触れられているが、テストを見た限りこの問題も解決されているように思う。
以上