狛ログ

2022年2月22日火曜日

【Laravel】ミドルウェアでクライアントからのリクエスト内容を書き換える。


オフィス狛 技術部のKoma(Twitterアカウントの中の人&CEO)です。

今回もLaravelネタになります。
前回、「Jetstream + Fortify」を画面無し(APIとして)で運用する為の方法を記載しました。
その中で、
if ($request->expectsJson()) {
    // クライアントからJSONレスポンスを要求されている場合、リダイレクトさせず、JSON形式メッセージをレスポンスする。
    return response()->json(['message' => 'Already authenticated.'], 200);
}
のような、記載をしたかと思います。
これは、とりあえず、「API化したものの、画面としても使える手段を残す為」となります。

前回は、特に説明しなかったのですが、$request->expectsJson()で、「APIとして呼ばれている」事を判断していました。
これ、正確にはクライアントに依存しているのですが、要は、httpヘッダに「Accept:application/json」を設定している、と言うことになります。
ただ、必ずしもクライアント側が設定してくるとは限らない・・・

そのような場合、クライアントからのリクエストを書き換えて、ヘッダに常に「Accept:application/json」を設定している、と言う状態にすることが出来ます。

まずは、ミドルウェアにクラスを追加します。
[app/Http/Middleware/RequireJson.php](新規追加)
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class RequireJson
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        // クライアントからのAccept要求(クライアントがResponseで欲しいデータ形式)は全てJSONとする。
        $request->headers->set('Accept','application/json');
    }
}
これでヘッダの書き換え処理は出来ました。
あとは、この処理が、クライアントからのリクエストの度に必ず呼ばれるようにしないといけません。

そこで、「Kernel.php」に上記のクラスを読み込む処理を追加します。
[app/Http/Kernel.php]
    protected $middleware = [
        \App\Http\Middleware\TrustProxies::class,
        \Fruitcake\Cors\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\RequireJson::class, // ←追加
    ];
これで完了となります。
※ただ、この設定をした時点で、完全に画面としては使用出来なくなるので、注意が必要です。

ミドルウェアは、色々使い道があるので、もっと使っていきたいですね。

0 件のコメント:

コメントを投稿