Laravelでリクエストが認証済みか判定する流れ
はじめに
Laravelでリクエストを受けた際、ミドルウェアでの認証判定の流れのメモです。
フレームワークの中を少し覗いてLaravelと仲良く(なった気に)なるシリーズです。
シリーズ
- Laravelがセッションを作成してから保存するまでの流れ
 - Laravelのログイン/ログアウト時のセッションの流れ
 - Laravelでリクエストが認証済みか判定する流れ
 
諸々
- 環境
- laravel 12
 
 - 参考
 
ミドルウェアの確認
実行されるミドルウェアは\Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,を実装しているIlluminate/Auth/Middleware/Authenticate.phpになります。
補足
※上記は、順番としては、Laravelのセッションの処理 (セッションインスタンスの作成) をする\Illuminate\Session\Middleware\StartSession::classミドルウェアのほぼ次に実行される。
[セッション作成]→[認証]のイメージ。
参考記事
1. AuthManagerインスタンスを作成する
Illuminate/Auth/Middleware/Authenticate.phpの__constructでAuthManagerインスタンスが作成される。
AuthManagerインスタンスは、認証を担当するガードクラスの作成を管理するクラスで次のセクションで活用される。(Authenticateクラス ← AuthManagerクラス ← ガードクラス)
2. ガードインスタンスを作成する
authenticateメソッド内の$this->auth->guard($guard)を実行。
ガードインスタンスは、AuthManagerインスタンス($this->auth)の$this->guardsプロパティに、config/auth.phpのguardsの値をキーにインスタンスキャッシュされる仕組み。
[
    'ガード名' => ***Guardインスタンス,
    'ガード名' => ***Guardインスタンス,
     ...
]
guard()メソッドの引数にガード名を指定することでそのガードインスタンスを取得または作成している。
(今回はドライバーの値はsessionなので、作成されるガードクラスはIlluminate/Auth/SessionGuard.php)
3. 認証済みか判定する
前のセクションで作成したSessionGuardクラスがuseしているGuardHelpersのcheck()メソッドで認証済みか判断する。
check()メソッドは中で呼んでいるuser()メソッドで、「セッションデータに認証ユーザーidがあり、DBからユーザーが取得できるか」を判断の材料として見ている。
 user()の補足 [⭐️重要]
認証できたパターン
- 
$id = $this->session->get($this->getName())で、セッションインスタンスの$this->attributesからユーザーIDを取得。 - ユーザーIDを取得できた場合は、ユーザープロバイダの
retrieveById($id)メソッドで認証ユーザーを取得。 - ガードインスタンスの
$this->userにセット。 
認証できなかったパターン
$this->userはnullのまま。
4. 認証済みの場合、セッションインスタンスとDBを更新する
前のセクションのuser()メソッドの続きで、$this->userがある場合は後半でupdateSessionメソッドも実行され、以下が行われる。
- セッションレコードに対して
- DBから既存のセッションレコードを削除
 
 - [セッションインスタンス]に対して(https://github.com/laravel/framework/blob/12.x/src/Illuminate/Session/Store.php)
- 
認証ユーザーのidを$this->attributes['login_xxx']にセット - 
再作成したセッションIDを$this->idにセット (セキュリティ対策) - また、セッションレコード新規作成するか更新するか判断するための
$this->existsプロパティをfalseに更新 (セッションレコード新規作成 or 更新は、レスポンスを返す前にStartSessionミドルウェアで実行される) 
 - 
 
 updateSessionの補足
updateSessionメソッドはログイン処理でも呼ばれています。
updateSessionメソッドの詳細は以下記事。
セッションレコード新規作成 or 更新の補足
レスポンス前にセッションレコード新規作成するか更新するかなどの判定はについては、以下記事の「10.セッションを保存する」セクションでも該当箇所のコードを掲載していますので参考にしてください。
シリーズ
- Laravelがセッションを作成してから保存するまでの流れ
 - Laravelのログイン/ログアウト時のセッションの流れ
 - Laravelでリクエストが認証済みか判定する流れ
 
Discussion