BackEnd

コードでわかるLaravelのブラウザ認証

投稿日:2020年11月30日 更新日:

はじめに

Laravel 8からは、認証機能のscaffoldとして、これまで推奨されていたLaravel UIの代わりに、Laravel Jetstreamが推奨されるようになりました(Laravel 8でも使用することはできます)。しかし、このLaravel Jetstreamが高機能で見た目が良いかわりに、細かなカスタマイズがしにくいことから、Laravel UIを採用するケースもあるようです。

認証機能の実装については、これらのライブラリを使用する他に、Laravelの認証クラスを直接使って、自前の認証機能を実装することもできます。

そこで、今回はLaravelのブラウザ認証クラスの処理の流れをコードを示しながら紹介します。

認証機能の概要

認証機能では、 guard と provider が重要な概念となります。

guard は、リクエスト毎にユーザーを認証する方法を定義しています。これには、セッションストレージとクッキーを使って状態を保持する SessionGuard と、トークンを使って認証する TokenGuard があります。

provider はデータベースなどの永続ストレージから、ユーザーを取得する方法を定義しています。これには、 Eloquent を使う EloquentUserProvider と、クエリビルダーを使う DatabaseUserProvider があります。

また、 guard と provider を自前で実装することもできます。

それでは、実際にコードを見てみましょう。

Controller

ログイン時、コントローラでは、 Auth ファサードの attempt() メソッドでユーザーを認証します。

Auth::attempt() に認証で使用するパラメータの配列を渡します。実際には、 SessionGuard クラスの attempt() メソッドが呼ばれます。

また、ログイン状態を維持したい場合は、 attempt() メソッドの第2引数に true を渡します。

なお、ユーザーを取得する条件は、例の通りである必要はありません。たとえば、 email の代わりに、 user_code などの何らかのユニークなカラムを指定することができます。さらに、 credentials['role'] = 1; などのように、追加の条件を付加することもできます。

Auth ファサードの guard() メソッドを使うと、使いたいguardインスタンスを指定することができます。これにより、異なる複数の認証処理を併用することができます。

SessionGuard

SessionGuard クラスでは、ユーザの認証、RememberTokenの更新、認証済みのユーザーインスタンスへのアクセスなどの機能を提供します。

SessionGuard クラスの attempt() メソッドを抜粋しました。順番に処理を見てきます。

fireAttemptEvent

初めに fireAttemptEvent() メソッドが呼ばれ、 Attempting イベントが発行されます。

retrieveByCredentials

ここでは、 auth.php で指定した UserProvider の retrieveByCredentials() メソッドが呼ばれ、 Illuminate\Contracts\Auth\Authenticatable 、もしくは、 null が返却されます。

hasValidCredentials

ここでは、(1)渡された認証情報を検証し、(2)成功すればイベントを発行します。

login

ここでは、(1)セッションストレージのIDを更新し、 $remember がtrueかつ、RememberTokenが空の場合、(2)新しいRememberTokenを発行して、(3)クッキーが更新されます。その後、(4) Login イベントが発行されて、認証されたユーザーがセットされ、 Authenticated イベントが発行されます。

fireFailedEvent

hasValidCredentials() メソッドで検証に失敗した場合、 Failed イベントが発行されます

EloquentUserProvider

UserProvider は、データベースなどの永続ストレージからユーザーを取得する機能を提供します。

retrieveByCredentials

SessionGuard クラスの attempt() メソッドから呼ばれます。渡された credentials をもとにユーザーを取得し、 model を返却します。

(1)渡された credentials をチェックし、問題があれば null を返却します。(2)認証用の model を返却します。(3)認証のためのクエリを組み立てます。(4)最初に見つかったユーザーを返却します。

retrieveByToken

SessionGuard クラスの userFromRecaller メソッドから呼ばれます。渡されたユーザーを識別する値をもとにユーザーを取得し、そのユーザーのRememberTokenとユーザーを比較して、 model または null を返却します。

(1)認証用の model を返却します。(2)認証のためのクエリを組み立て、最初に見つかったユーザーを返却します。(3)ユーザーが見つからなければ null を返却します。(4)見つかったユーザーのRememberTokenを取得します。(5)渡されたRememberTokenとユーザーのRememberTokenを比較し、一致すればユーザーを、一致しなければ null を返却します。

DatabaseUserProvider

EloquentUserProvider と同じく、データベースなどの永続ストレージからユーザーを取得する機能を提供します。 EloquentUserProvider では、ユーザーの取得にEloquentを使っていましたが、こちらはクエリビルダーを使います。

retrieveByCredentials

SessionGuard クラスの attempt() メソッドから呼ばれます。渡された credentials をもとにユーザーを取得し、 model を返却します。

(1)渡された credentials をチェックし、問題があれば null を返却します。(2)認証のためのクエリを返却します。(3)認証のためのクエリを組み立てます。(4)最初に見つかったユーザーを返却します。(5)ユーザーを Illuminate\Auth\GenericUser に変換して返却します。

retrieveByToken

SessionGuard クラスの userFromRecaller メソッドから呼ばれます。渡されたユーザーを識別する値をもとにユーザーを取得し、そのユーザーのRememberTokenとユーザーを比較して、 model または null を返却します。

(1)認証のためのクエリを組み立て、最初に見つかったユーザーを返却します。(2)渡されたRememberTokenとユーザーのRememberTokenを比較し、一致すればユーザーを、一致しなければ null を返却します。

さいごに

Laravelのブラウザ認証の流れをコードを示しながら紹介しました。API認証の方も、似たような流れになっています。API認証に興味があれば、よければこちらの記事もご覧ください。

おすすめ書籍

PHPフレームワークLaravel入門 第2版 初めてのPHP

blog-page_footer_336




blog-page_footer_336




-BackEnd
-,

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。


comment

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA


関連記事

laravel logo

Laravelの認可機能Gateを使ってみた

はじめに Laravelには認可機能を簡単に実装出来るGateという機能が用意されているので使ってみました。 やる事 よくあるユースケースとして、ユーザー毎に画面の閲覧権限とPOST権限を作ってみたい ...

Go言語

Go言語で使えるmigrationライブラリ

はじめに Go言語の連載8回目です。今回はGo言語でWeb開発をする際に使うDB関連のライブラリとして、migrationに絞って調べてみました。 migrationライブラリ Go言語のmigrat ...

Stripe Connectを使って複合プランの継続課金を実装

はじめに 今回の記事は、Stripe Connectを使ってCheckoutを利用した継続課金を実装の続きとなります。 前回に引き続き、継続課金の実装について紹介していきます。今回は、実際のサービスで ...

rails

【Puma】アプリサーバのチューニング

はじめに みなさん、アプリサーバのチューニングはどのように行っていますか? 私の場合、使うサーバのスペックがだいたい同じくらいなので、過去の設定ファイルを使いまわしていました。 そんな中、先日本番環境 ...

Docker上のLaravelのログをFluentdに出力する

はじめに こんにちは。前回に続いてログの扱いをあれこれ調べてました。今回はログ集約をやってみたくてFluentdについてです。Docker上に構築したLaravelだとどうやるのかを調べています。 環 ...

フォロー

blog-page_side_responsive

2020年11月
日 月 火 水 木 金 土
1234567
891011121314
15161718192021
22232425262728
2930  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。