【Laravel8】認証の仕組みをざっくり理解する(laravel・JetStream、inertia.js)

初めに

Laravel8では認証にJetStreamが追加されましたが、内部で行われているログイン処理はこれまでのバージョンと大きく変わりません。また、認証のコア処理部分はFortifyというパッケージを利用しています。

なお説明の都合上、具体的なURLを以下のように定義します。

認証が必要なルート:/dashboard 
認証が不要なルート:/login、/register

ログイン画面が表示されるまでの流れ

1.定義済みのルート一覧を確認する(だいじ)

まず、ログイン画面が表示されるURLの/loginのルーティングをルーティングファイルであるweb.phpで確認しても見つけることができません。そのため、以下コマンドで定義済みのルーティング一覧を確認します。

php artisan route:list

表示されたリストのaction列を見ると、以下のようにメソッドが実行されています。

  • /loginにgetでアクセスした場合はLaravel\Fortify\Http\Controllers\AuthenticatedSessionController@create
  • /loginにpostでアクセスした場合はLaravel\Fortify\Http\Controllers\AuthenticatedSessionController@store
今回は、ログイン画面を表示する流れを例に以下を見ていきたいと思います。

2.ログイン画面をレンダーする処理を特定する

ルーティングに定義されているLaravel\Fortify\Http\Controllers\AuthenticatedSessionControllerを見てみると、AuthenticatedSessionController.phpファイルのcreateメソッドがあります。createメソッドの中ではapp(LoginViewResponse::class)を実行しています。
public function create(Request $request): LoginViewResponse
{
  return app(LoginViewResponse::class);
}

上記に関連する内容はvendor¥laravel¥jetstream¥srcのJetstreamServiceProvider.phpに記述されており、このファイルの内容を確認することでログイン画面の表示の流れを理解することができます。

JetstreamServiceProvider.phpはサービスプロバイダーファイルなのでbootメソッドとregisterメソッドを持ちます。boot()の中では、jetstream.stackがinertiaの場合のみbootInertiaが実行されていることが確認できます。

public function boot() { if(config('jetstream.stack')==='inertia'){ $this->bootInertia()}}

bootInertiaメソッドを確認すると以下のように、middlewareにShareInertiaDataをappendしているメソッドを見つけることができます。ここで、Auth/Login.vueをレンダーすることで、ログイン画面を表示しているわけです。

protectedfunctionbootInertia(){ Fortify::loginView(function () { return Inertia::render('Auth/Login', [ 'canResetPassword' => Route::has('password.request'), 'status' => session('status'), ]); })}

ログイン直後のリダイレクト先を変える方法

Laravel8だと、ログイン直後の遷移先が「dashboard」になっているので、これを変えたい場合がありますよね。(ログイン直後にいきなり一覧画面とかを表示したい場合など)

Laravel6.8以降なら、/app/Providers/RouteServiceProvider.php の以下を変えてあげれば可能です。

publicconstHOME='/dashboard';

このHOMEで指定したパスにリダイレクトされるようになります。
※キャッシュが残っていて反映しない場合があるので、その時は以下コマンドを実行してください

php artisan config:clear

現在ログイン状態で、認証がされていない場合にのみ遷移可能にしたいルートにアクセスした際にリダイレクトするパスの設定

ちょっとわかりにくいですが、例えば認証済みの状態で、 /login や /register へ遷移しようとした場合が該当します。こういったルートは未認証の場合のみ遷移できるように制御する必要があります。

処理は、RedirectIfAuthenticatedクラス(App\Http\Middleware\RedirectIfAuthenticated.php)に記載されています。

下記のredirect()の箇所で指定されているパスにリダイレクトされるようになっているので、
ここを変えてあげれば任意のパスに遷移することが可能です

※通常、ログイン直後のリダイレクト先と同じはずであるという前提があるため、
HOMEが指定されています。

foreach ($guards as $guard) {
    if (Auth::guard($guard)->check()) {
    return redirect(RouteServiceProvider::HOME);
  }
}

ネームスペースでわかる通り、RedirectIfAuthenticatedクラスはミドルウェアで、開発中のアプリケーションで利用されるミドルウェアはApp\Http\Kernelクラスに記述されます。

ちなみに、RedirectIfAuthenticatedクラスはguestという名前で定義されています。

protected $routeMiddleware = [ 
  'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 
];

未認証の状態で、認証が必要なルートにアクセスした際にリダイレクトするパスの設定

例えば、ログインする前にURLに直接 /dashboard へアクセスした場合です。
下記箇所に設定されています。基本的にはログイン画面にリダイレクトできれば良いので、変更の必要性はあまり生じないかと思います。
protected function redirectTo($request)
{
  if (! $request->expectsJson()) {
    return route('login');
  }
}

おまけ(LoginControllerは何処に)

これまでのLaravelではログイン機能をインストールすると「app/Http/Controllers/Auth/LoginController.php」というファイルが存在していましたが、Laravel 8.xからはJetstreamを使うようになり、このファイルが不要になってしまったので、必要な場合は別途作成する必要があります。

コメント

タイトルとURLをコピーしました