概要
laravelにはartisan downコマンドというサイト全体をメンテナンスモードに切り替えるコマンドがある。自分が開発に携わったWebサイトでも、外部からのアクセスを閉じてリリース作業とかしたい時にこのコマンドでアクセス制限をかけたりとかしている。
バージョン11の場合、メンテナンスモードの時も--sercretオプションを利用すると指定したシークレットキーをURLにつけてアクセスすることでメンテナンスモード中のサイトにアクセス出来るようになる。リリース後の動作確認などでよくお世話になっています。
このサイトがある外部システムと連携することになり、連携時にその外部システムからサイト側へPOST処理が発生するのだがこの機能だけメンテナンスモード中でも制限せずに動かしたい。
ので、外部システムがアクセスしてくるURLだけメンテナンスの対象外にすることは出来ないだろうかと考えたのだが、ミドルウェアで実現できそうだった。
実装
メンテナンスに関する機能はvendor内のPreventRequestsDuringMaintenanceというミドルウェアに集約されている。
これをオーバーライドして特定URLの除外処理を実装するのが早いというかシンプルに解決できた。
まずはミドルウェア作成
php artisan make:middleware PreventRequestsDuringMaintenance.php
これでapp/Http/Middleware/にミドルウェアファイルが作成される。
中味はこんな感じ。
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
class PreventRequestsDuringMaintenance extends Middleware
{
protected $except = [
'/test/*',
];
}
ほぼ突貫で対応したようなものなのでもう少し綺麗なやり方がありそうだが・・・除外対象にしたいURLをまとめた配列を用意してあげるだけ。あとは元のミドルウェア内にあるinExceptArrayメソッドで該当URLがメンテ対象とするかどうかを判別して処理してくれる。
あとはこのミドルウェアを登録する。
laravel10までだとapp\Http\Karnel.phpに作成したミドルウェアを登録すればOKだったが、laravel11から大きく仕様が変わっていた。
->withMiddleware(function (Middleware $middleware) {
$middleware->replace(
\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
PreventRequestsDuringMaintenance::class
);
})
これで標準のミドルウェアを今回作成したミドルウェアに差し替えた。
laravel7までは接続元IPアドレスを--allowオプションで指定すればメンテナンスの除外対象にすることが出来たがシークレットキーの仕様になってから外部から自動アクセスしてくる分をどう対象外にしようかと思っていたので何とか?対応出来たかもしれない。
ミドルウェアの登録方法については11でかなり変わっていたのでちょっと色々戸惑った。