LaravelでAPI用のAuthMiddlewareの返り値の型設定について

PHP

Laravel

はじめに

Laravelで作成したAPIでsessionを使用した認証を扱いました。

その際に認証のMiddlewareを作成したので、設定や返り値の型の注意点について共有できればと思います。

実際のコード

早速ですが、実際に作成したコードは以下のようになります。

app/Http/Middleware/AdminAuth.php
<?php namespace App\Http\Middleware; use App\Exceptions\UnauthorizedException; use Closure; use Illuminate\Http\JsonResponse; use Illuminate\Http\Response; use Illuminate\Support\Facades\Auth; use Illuminate\Http\Request; class AdminAuth { /** * @param Request $request * @param Closure $next * @return JsonResponse|Response */ public function handle(Request $request, Closure $next): JsonResponse|Response { if (!Auth::guard('admin')->check()) { return response()->json([ 'message' => UnauthorizedException::MESSAGE ], 401); } return $next($request); } }

ここで、UnauthorizedException は自作したExceptionとなります。

このMiddlewareで行っていることは単純で、

Auth::guard('admin')->check()

で、'admin'のguardで認証できているかをチェックします。

このMiddlewareはAPI用であるため、認証のチェックがうまくいっていない場合には、JsonResponse型で401を返却します。

Middlewareの登録

Middlewareをroute定義の際に使用する場合には、app/Http/Kernel.php クラスの$routeMiddleware プロパティに作成したMiddlewareを以下のように登録する必要があります。

app/Http/Kernel.php
protected $routeMiddleware = [ // 中略 'auth.admin' => \App\Http\Middleware\AdminAuth::class ];

この記述を行うことによって、ルート定義の際に middleware メソッドを使用して作成したMiddlewareをルートに割り当てることができます。

以下は、使用例です。

routes/api.php
Route::prefix('/admin')->middleware('auth.admin')->group(function () { // routeとControllerの定義 });

これで、/admin 以下のパスは admin で認証されていない場合は、401のステータスコードでレスポンスが返ることとなります。

返り値の型について

このMiddlewareの返り値の型は JsonResponse|Response となっていますが、こちらについて解説していきます。

$next で実行される Controller では、基本的に全て JsonResponse を返却しています。 ですので、このMiddlewareの返り値の型は本来であれば、JsonResponse のみであるべきなのですがその他に、Response が定義されています。

これは、Controller内でエラーが起きた時のために定義します。 LaravelはデフォルトでExceptionをキャッチした際にはHTTPレスポンスへ変換されます。

そのため、Contoller内でエラーが起きた際には \Illuminate\Http\Response が返却され、Middleware 内で JsonResponse しか型定義していない場合は、$next($request) の行で TypeError としてエラーハンドリングされてしまいます。

これでは、開発時のデバッグ等がとてもやりにくくなってしまいます。 このため、handle メソッドの返り値の型は JsonResponse|Response としておくと良いでしょう。

最後に

Laravelでは、App\Exceptions\Handler クラスで全ての例外を処理します。

これをカスタマイズすることで、自作Middlewareの返り値の型を JsonResponse のみにしても大丈夫そうな書き方ができそうなので、これについてもっと学習してここでまた共有できればと思います。

みきどーざん

@take_cantik

目次