Laravelでリクエストが認証済みか判定する流れ

に公開

はじめに

Laravelでリクエストを受けた際、ミドルウェアでの認証判定の流れのメモです。

フレームワークの中を少し覗いてLaravelと仲良く(なった気に)なるシリーズです。

シリーズ

諸々

ミドルウェアの確認

https://github.com/laravel/framework/blob/f717cce43c02e809c1ea77811ee46bb5e06b616d/src/Illuminate/Foundation/Http/Kernel.php#L96-L115

実行されるミドルウェアは\Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,を実装しているIlluminate/Auth/Middleware/Authenticate.phpになります。

補足

※上記は、順番としては、Laravelのセッションの処理 (セッションインスタンスの作成) をする\Illuminate\Session\Middleware\StartSession::classミドルウェアのほぼ次に実行される。

[セッション作成]→[認証]のイメージ。

参考記事
https://zenn.dev/shun_nakamura/articles/6e6f367488bb0f

1. AuthManagerインスタンスを作成する

Illuminate/Auth/Middleware/Authenticate.php__constructAuthManagerインスタンスが作成される。

AuthManagerインスタンスは、認証を担当するガードクラスの作成を管理するクラスで次のセクションで活用される。(Authenticateクラス ← AuthManagerクラス ← ガードクラス)

https://github.com/laravel/framework/blob/f717cce43c02e809c1ea77811ee46bb5e06b616d/src/Illuminate/Auth/Middleware/Authenticate.php#L27-L35

2. ガードインスタンスを作成する

authenticateメソッド内の$this->auth->guard($guard)を実行。

ガードインスタンスは、AuthManagerインスタンス($this->auth)の$this->guardsプロパティに、config/auth.phpguardsの値をキーにインスタンスキャッシュされる仕組み。

[
    'ガード名' => ***Guardインスタンス,
    'ガード名' => ***Guardインスタンス,
     ...
]

guard()メソッドの引数にガード名を指定することでそのガードインスタンスを取得または作成している。
(今回はドライバーの値はsessionなので、作成されるガードクラスはIlluminate/Auth/SessionGuard.php)

https://github.com/laravel/framework/blob/f717cce43c02e809c1ea77811ee46bb5e06b616d/src/Illuminate/Auth/Middleware/Authenticate.php#L49-L88

https://github.com/laravel/framework/blob/f717cce43c02e809c1ea77811ee46bb5e06b616d/src/Illuminate/Auth/AuthManager.php#L59-L101

3. 認証済みか判定する

前のセクションで作成したSessionGuardクラスがuseしているGuardHelperscheck()メソッドで認証済みか判断する。

check()メソッドは中で呼んでいるuser()メソッドで、「セッションデータに認証ユーザーidがあり、DBからユーザーが取得できるか」を判断の材料として見ている。

https://github.com/laravel/framework/blob/12.x/src/Illuminate/Auth/GuardHelpers.php#L49-L57

user()の補足 [⭐️重要]

認証できたパターン

  1. $id = $this->session->get($this->getName())で、セッションインスタンスの$this->attributesからユーザーIDを取得
  2. ユーザーIDを取得できた場合は、ユーザープロバイダretrieveById($id)メソッドで認証ユーザーを取得
  3. ガードインスタンスの$this->userにセット

認証できなかったパターン

$this->usernullのまま。

https://github.com/laravel/framework/blob/aa0be9eed00223cdd7280a226670ca489d7f5d50/src/Illuminate/Auth/SessionGuard.php#L156-L197

https://github.com/laravel/framework/blob/f717cce43c02e809c1ea77811ee46bb5e06b616d/src/Illuminate/Auth/EloquentUserProvider.php#L46-L59

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メソッドの詳細は以下記事。

https://zenn.dev/shun_nakamura/articles/0d3bf38cb80cf5#2.新規のセッションのレコードを作成する

セッションレコード新規作成 or 更新の補足

レスポンス前にセッションレコード新規作成するか更新するかなどの判定はについては、以下記事の「10.セッションを保存する」セクションでも該当箇所のコードを掲載していますので参考にしてください。

https://zenn.dev/shun_nakamura/articles/6e6f367488bb0f#10.セッションを保存する

シリーズ

Discussion