🎨

[図解] Laravel の認証周りのややこしいあれこれ。

2021/05/10に公開

Laravel のログイン認証周りのカスタマイズをする度、
「この場合どこをいじればいいんだっけ・・・」と混乱するので、
図にまとめてみました。

全体感を掴んでいただくことが目的ですので、
この記事では、具体的なカスタマイズのコードは紹介しません。
ご了承ください。

まずは登場人物一覧

ガード (guard)

Laravel では「認証」と呼ぶことが多いです。
ログイン機構の種類を表します。

たとえば、ECサイトの「管理者」と「会員」など。
ログイン画面の数だけガードがある、というイメージです。

provider (認証方法) と driver (認証状態の管理方法) で構成されています。

config/auth.php に定義されており、追加・変更ができます。

ガードドライバ (driver)

ログインの認証状態をどうやって管理するか
多くの場合はセッション認証 (session) です。

セッションを利用できないAPI認証の場合は、トークン認証 (token) の場合もあるでしょう。

Auth::extend() で独自のものを追加できます (AuthServiceProviderに記述)。

※ソース上では driver としか表現されていないのですが、
プロバイダの driver と紛らわしいので、ガードドライバと呼びます。

プロバイダ (provider)

認証の方法。
つまり、誰 (モデル) をどんなロジック (プロバイダドライバ) で、ログインさせるか。

config/auth.php に定義されており、追加・変更ができます。

モデル (model)

誰をログインさせるか。

多くの場合は、ログインユーザを管理しているテーブルに対応する、モデルクラスです。
このモデルクラスは、 Authenticatable インターフェイスを実装している必要があります。

プロバイダドライバ (driver)

ログイン認証の中核となるロジック。
具体的には、パスワードをどのように検証し、どのような条件ならログインを許可するか、等。

実体は UserProvider クラスと Hasher クラスの組み合わせです。

Auth::provider() で独自のものを追加できます (AuthServiceProviderに記述)。

※ソース上では driver としか表現されていないのですが、
ガードの driver と紛らわしいので、プロバイダドライバと呼びます。

UserPrvider クラス

Laravel の認証機能における最重要クラス

ログイン画面から Post されたログイン情報 (Credential) に対して成否を判定したり、
その結果取得されたユーザ情報に対して、ログインをさせてよいかどうかを判定したりします。

あくまでクラスなので自由に作ることができますが、Illuminate\Contracts\Auth\Authenticatable を implements する必要があります。

Hasher クラス

ユーザ登録時やパスワード変更時に、パスワードをハッシュしたり、
ログイン試行時にパスワードがハッシュ値と一致するかどうかを判定したりするクラスです。

こちらも自由に作ることができますが、
Illuminate\Contracts\Hashing\Hasher を implements する必要があります。

ゲート (Gate)

本記事では触れませんが、一応。

いわゆる「権限」です。
Laravel では「認可 (Gate)」 と呼ばれ、
ログイン中のユーザが特定の操作を実行できるかどうかを判断するものです。

Gate::define() で定義します (AuthServiceProviderに記述)。

マルチ認証を実装する場合

たとえば、ECサイトで、管理者用のログイン画面(と管理画面)、
会員用のログイン画面(とマイページ) を、
それぞれ実装しなければいけないような場合です。

この場合に実装しなければいけないのは、以下の範囲になります。

まず、2種類のログイン機構が存在するため、ガードを2つに分けます。

管理者と会員が異なるテーブルで管理されている前提で考えると、
それぞれのモデルが必要です。

必然的に、ログイン対象のモデルを管理している「プロバイダ」も2つに分けることになります。

複雑なログイン条件を追加する場合

例えば、ユーザがログインできるかどうかを判定する際、
ユーザテーブルとは別の、料金支払テーブルを参照しなければいけないような場合です。

この場合に実装しなければいけないのは、以下の範囲になります。

このような条件判定を行うのは、ユーザプロバイダ (UserProvider) クラスです。

このクラスを独自に作成した上で、
その上位概念である「プロバイダドライバ」を独自に定義し、
さらに「プロバイダ」の定義を変更する必要があります。

なお、認証条件を追加する場合でも、
ユーザテーブルにもつ情報のみで完結する場合は、
LoginController のカスタマイズのみで対応することができます。

パスワードハッシュ方式を変更する場合

例えば、データ移行の都合により、パスワードのハッシュ方式として、
Laravel が標準でサポートしていない pbkdf2 アルゴリズムを使用するような場合です。

この場合に実装しなければいけないのは、以下の範囲になります。

この場合はハッシャークラスを独自に作成した上で、
やはり、その上位概念である「プロバイダドライバ」を独自に定義し、
「プロバイダ」の定義を変更する必要があります。

Discussion