Laravel 8.x 認証

イントロダクション

Laravelでは簡単に認証が実装できます。実のところ、ほぼすべて最初から設定済みです。認証の設定ファイルはconfig/auth.phpに用意してあり、認証サービスの振る舞いを調整できるように、読みやすいコメント付きでたくさんのオプションが用意されています。

Laravelの認証機能は「ガード」と「プロバイダ」を中心概念として構成されています。ガードは各リクエストごとに、どのようにユーザーを認証するかを定義します。たとえば、Laravelにはセッションストレージとクッキーを使いながら状態を維持するsessionガードが用意されています。

プロバイダは永続ストレージから、どのようにユーザーを取得するかを定義します。LaravelはEloquentとデータベースクリエビルダを使用しユーザーを取得する機能を用意しています。しかし、アプリケーションの必要性に応じて、自由にプロバイダを追加できます。

混乱しても心配ありません。通常のアプリケーションでは、デフォルトの認証設定を変更する必要はありません。

てっとり早く始める

早速使い始めたいですか?真新しくインストールしたLaravelパッケージへ、Laravel Jetstream和訳)をインストールしてください。データベースをマイグレーションしたら、/registerへブラウザでアクセスするか、アプリケーションに割り付けた別のURLへアクセスしましょう。Jetstreamは認証システム全体のスカフォールディングを面倒見ます!

データベースの検討事項

Laravelはデフォルトで、app/Modelsディレクトリの中にApp\Models\User Eloquentモデルを設置します。このモデルは、デフォルトのEloquent認証ドライバと共に使用します。アプリケーションでEloquentを使用しない場合は、Laravelのクエリビルダを使用するdatabase認証ドライバを使用することになるでしょう。

App\Models\Userモデルのデータベーススキマーを構築するときは、パスワードカラムが最低でも60文字確保してください。デフォルトの文字列カラム長である255文字のままにしておくのは、良い選択です。

さらにusers、もしくは同等の働きをするテーブルには、100文字のremember_token文字列カラムも含めてください。このカラムはログイン時に、アプリケーションで"remember me"を選んだユーザーのトークンを保存しておくカラムとして使用されます。

エコシステム概論

Laravelは、認証に関連するパッケージをいくつか提供しています。説明を続ける前にLaravelにおける一般的な認証のエコシステムを確認し、各パッケージの使用目的について説明します。

最初に、認証の仕組みを考えましょう。Webブラウザを使用するとき、ユーザーはログインフォームを介してユーザー名とパスワードを入力します。この認証情報が正しい場合、アプリケーションは認証したユーザーに関する情報をユーザーのセッションに保存します。ブラウザへ発行されたCookieにはセッションIDが含まれているため、アプリケーションへの後続のリクエストでユーザーを正しいセッションに関連付けできます。セッションクッキーを受信すると、アプリケーションはセッションIDに基づいてセッションデータを取得し、認証情報がセッションに格納されていることに注意して、ユーザーを「認証済み」と見なします。

APIへアクセスするためにリモートサービスが認証を必要とする場合、Webブラウザがないためクッキーを通常使用しません。代わりにリモートサービスは、リクエストごとにAPIトークンをAPIに送信します。アプリケーションは有効なAPIトークンのテーブルに照らし合わせ受信トークンを検証し、そのAPIトークンに関連付けられているユーザーが実行しているリクエストを「認証」できます。

Laravel組み込みのブラウザ認証サービス

Laravelは、通常AuthおよびSessionファサードを介してアクセスする組み込み認証とセッションサービスを用意しています。これらの機能はWebブラウザから開始されたリクエストにクッキーベースの認証を提供しています。ユーザーの認証情報を確認し、そのユーザーを認証するメソッドを提供しています。さらに、これらのサービスは適切なデータをユーザーのセッションに自動的に保存し、適切なセッションクッキーを発行します。こうしたサービスの使用方法は、このドキュメントに記載しています。

Jetstream / Fortify

このドキュメント中で説明するように、こうした認証サービスを自分で操作して、アプリケーション独自の認証レイヤーを構築できます。しかし、より迅速に開始できるよう、認証レイヤー全体の堅牢で最新のスカフォールドを提供する無料パッケージをリリースしました。[Laravel Jetstream](https://jetstream.laravel.com)(和訳)と[Laravel Fortify](https://github.com/laravel/fortify)パッケージです。

Laravel Fortifyは、Laravelのヘッドレス認証バックエンドであり、このドキュメントにある多くの機能を実装しています。Laravel Jetstreamは、Tailwind CSSLaravel LivewireInertia.jsを使い、美しくモダンなUIでFortifyの認証サービスを利用および公開するUIです。Laravel Jetstreamは、ブラウザベースのクッキー認証の提供に加えAPIトークン認証を提供するため、Laravel Sanctumとの統合を組み込んでいます。LaravelのAPI認証サービスについては、以下で説明します。

LaravelのAPI認証サービス

Laravelは、APIトークンの管理とAPIトークンで行われたリクエストの認証を支援する2つのオプションパッケージを提供しています。PassportSanctumです。これらのライブラリとLaravelの組み込みCookieベースの認証ライブラリは互いに排他的でないことを注意してください。これらのライブラリは主にAPIトークン認証に重点を置いていますが、組み込みの認証サービスはクッキーベースのブラウザ認証に重点を置いています。多くのアプリケーションは、Laravelの組み込みクッキーベースの認証サービスと、LaravelのAPI認証パッケージのどちらか1つの、両方を使用するでしょう。

Passport

PassportはOAuth2認証プロバイダーであり、さまざまなタイプのトークンを発行できる多様なOAuth2「許可タイプ」を提供します。大まかに言えば、これはAPI認証の堅牢で複雑なパッケージです。ただ、ほとんどのアプリケーションはOAuth2仕様が提供する複雑な機能を必要としないため、ユーザーと開発者の両方が混乱する可能性があります。さらに、開発者はこれまで、Passportと同じようなOAuth2認証プロバイダーを使用してSPAアプリケーションまたはモバイルアプリケーションを認証する方法について混乱させられてきました。

Sanctum

OAuth2の複雑さと開発者の混乱に対応するため、WebブラウザからのファーストパーティWebリクエストと、トークンによるAPIリクエストの両方を処理できる、よりシンプルで合理化された認証パッケージの構築に着手しました。このゴールは、Laravel Sanctumのリリースで達成できました。これは、APIに加えファーストパーティのWeb UIの提供、もしくはバックエンドのLaravelアプリケーションから独立して存在するシングルページアプリケーションやモバイルクライアントを提供するアプリケーション向きの推奨認証パッケージと考えてください。

Laravel Sanctumは、アプリケーションの認証プロセス全体を管理できるハイブリッドWeb/API認証パッケージです。Sanctumベースのアプリケーションがリクエストを受信すると、まずSanctumはリクエストに認証済みセッションを参照するセッションクッキーが含まれているかどうかを判断するため、これが可能になります。Sanctumは、これまでに説明したLaravelの組み込み認証サービスを呼び出すことでこれを実現しますリクエストがセッションクッキーを介して認証されていない場合、SanctumはAPIトークンのリクエストを検査します。APIトークンが存在する場合、Sanctumはそのトークンを使用してリクエストを認証します。このプロセスの詳細については、Sanctumの"動作の仕組み"ドキュメントをご覧ください。

Laravel Sanctumは、Laravel Jetstream和訳)認証スカフォールドに含める選択をしたAPIパッケージです。なぜなら、Webアプリケーションの認証ニーズの大部分に最適であると考えているためです。

まとめと選択方法

要約すると、ブラウザを使用してアプリケーションにアクセスする場合、アプリケーションはLaravelの組み込み認証サービスを使用します。

次に、アプリケーションがAPIを提供する場合は、PassportまたはSanctumを選択してください。「スコープ」や「アビリティ」のサポートを含むAPI認証やSPA認証、モバイル認証のためのシンプルで完全なソリューションであるため、一般に、可能であればSanctumをお勧めします。

アプリケーションがOAuth2仕様で提供されるすべての機能を絶対に必要とする場合、Passportを選択してください。。

また、すぐに使い始めたい場合は、新しいLaravelアプリケーションをすばやく開始するための迅速な方法として、Laravelの優先認証スタックである組み込み認証サービスとLaravel Sanctumを始めから使用している、Laravel Jetstream和訳)をおすすめします。

認証クイックスタート

Note: ドキュメントのこの部分では、Laravel Jetstream和訳)パッケージを使用したユーザーの認証について説明します。これには、すぐに使い始めるのに役立つUIのスカフォールドが含まれています。Laravelの認証システムを直接統合したい場合は、手動のユーザー認証のドキュメントをご覧ください。

ルート定義

Laravel'のlaravel/jetstreamパッケージは、簡単なコマンドで認証に必要なルートとビュー、バックエンドのロジックを素早くすべてスカフォールドする方法を提供します。

composer require laravel/jetstream

// Livewireスタックを使用するJetstreamをインストールする
php artisan jetstream:install livewire

// Inertiaスタックを使用するJetstreamをインストールする
php artisan jetstream:install inertia

このコマンドは真新しくインストールしたアプリケーションで使用してください。認証の全エンドポイントに対するルートと同時に、レイアウトビュー、登録とログインビューをインストールします。ログイン後のリクエストを処理するため、アプリケーションのダッシュボードを/dashboardルートとして生成します。

認証を含むアプリケーションの生成

真新しいアプリケーションを開始し、認証のスカフォールドを含めたい場合は、アプリケーションの生成時にLaravelインストーラへ--jetディレクティブを使ってください。このコマンドはアプリケーションへ認証スカフォールドを全部インストールし、コンパイルします。

laravel new kitetail --jet

Tip!! Jetstreamの詳細は、公式Jetstreamドキュメント和訳)をご覧ください。

ビュー

前セクションで述べた通り、laravel/jetstreamパッケージのphp artisan jetstream:installコマンドは、認証に必要なビューをすべて生成し、resources/views/authディレクトリへ設置します。

Jetstreamはアプリケーションのベースレイアウトを含むresources/views/layoutsディレクトリも生成します。これらのビューはすべてTailwind CSSフレームワークを使用していますが、ご希望であれば自由にカスタマイズできます。

認証

これでアプリケーションが認証用にスカフォールドされたので、ユーザー登録して認証する準備ができました。Jetstreamの認証コントローラには既存のユーザーを認証してデータベースに新しいユーザーを保存するロジックがすでに含まれているため、ブラウザでアプリケーションにアクセスするだけです。

パスのカスタマイズ

Wユーザーが認証に成功した場合、典型的には/homeのURIへリダイレクトすると思います。RouteServiceProviderHOME定数を定義することにより、認証後のリダイレクトパスをカスタマイズできます。

public const HOME = '/home';

Laravel Jetstreamを使う場合、Jetstreamのインストール処理はHOMEの値を/dashboardへ変更します。

認証済みユーザーの取得

受信リクエストを処理しているとき、Authファサードにより認証済みユーザーへアクセスできます。

use Illuminate\Support\Facades\Auth;

// 現在認証されているユーザーの取得
$user = Auth::user();

// 現在認証されているユーザーのID取得
$id = Auth::id();

もしくは、ユーザーが一度認証したら、Illuminate\Http\Requestインスタンスによりその認証済みユーザーへアクセスできます。コントローラのメソッドでタイプヒントされたクラスは、自動的に注入されることを思い出してください。Illuminate\Http\Requestオブジェクトをタイプヒントすることにより、アプリケーションのどのコントローラでも認証ユーザーへ簡単にアクセスできます。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FlightController extends Controller
{
    /**
     * 利用可能な全フライトの取得
     *
     * @param  Request  $request
     * @return Response
     */
    public function update(Request $request)
    {
        // $request->user()は認証済みユーザーのインスタンスを返す
    }
}

現在のユーザーが認証されているか調べる

ユーザーがすでにアプリケーションにログインしているかを調べるには、Authファサードのcheckメソッドが使えます。認証時にtrueを返します。

use Illuminate\Support\Facades\Auth;

if (Auth::check()) {
    // ユーザーはログインしている
}

Tip!! checkメソッドを使っても、あるユーザーが認証済みであるかを判定可能です。特定のルートやコントローラへユーザーをアクセスさせる前に、認証済みであるかをミドルウェアにより確認する場面で、典型的に使用します。より詳細についてはルートの保護のドキュメントを参照してください。

ルートの保護

ルートミドルウェアは特定のルートに対し、認証済みユーザーのみアクセスを許すために使われます。LaravelにはIlluminate\Auth\Middleware\Authenticateクラスの中で参照されているauthミドルウェアを最初から用意しています。このミドルウェアは、HTTPカーネルで登録済みのため、必要なのはルート定義でこのミドルウェアを指定するだけです。

Route::get('flights', function () {
    // 認証済みのユーザーのみが入れる
})->middleware('auth');

未認証ユーザーのリダイレクト

ミドルウェアが未認証ユーザーを突き止めると、ユーザーをlogin名前付きルートへリダイレクトします。この振る舞いは、app/Http/Middleware/Authenticate.phpファイルのredirectTo関数で変更できます。

/**
 * ユーザーをリダイレクトさせるパスの取得
 *
 * @param  \Illuminate\Http\Request  $request
 * @return string
 */
protected function redirectTo($request)
{
    return route('login');
}

ガードの指定

authミドルウェアをルートに対し指定するときに、そのユーザーに対し認証を実行するガードを指定することもできます。指定されたガードは、auth.php設定ファイルのguards配列のキーを指定します。

Route::get('flights', function () {
    // 認証済みのユーザーのみが入れる
})->middleware('auth:api');

認証回数制限

Laravel Jetstreamの利用時、自動的にログインの試みは回数制限されます。何度かログイン情報の入力へ失敗すると、そのユーザーはデフォルトで一分間ログインできなくなります。制限はユーザーのユーザー名/メールアドレスとIPアドレスの組み合わせで制限されます。

Tip!! ルートをレート制限する場合は、レート制限のドキュメントを確認してください。

自前のユーザー認証

Laravel Jetstreamが用意する認証スカフォールドを使う必要はないことに留意してください。このスカフォールドを使用しない選択をした場合、Laravelの認証クラスを直接使用し、ユーザーの認証管理を行う必要があります。心配ありません。それも簡単です!

Laravelの認証サービスにはAuthファサードでアクセスできます。クラスの最初でAuthファサードを確実にインポートしておきましょう。次にattemptメソッドを見てみましょう。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    /**
     * 認証を処理する
     *
     * @param  \Illuminate\Http\Request $request
     *
     * @return Response
     */
    public function authenticate(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if (Auth::attempt($credentials)) {
            // 認証に成功した
            return redirect()->intended('dashboard');
        }
    }
}

attemptメソッドは最初の引数として、キー/値ペアの配列を受け取ります。配列中の他の値は、データベーステーブルの中からそのユーザーを見つけるために使用されます。そのため、上の例ではemailカラム値によりユーザーが取得されます。データベース中のハッシュ済みパスワードと比較する前に、フレームワークは自動的に値をハッシュ化するため、passwordへ指定する値はハッシュ化しないでください。2つのハッシュ済みパスワードが一致したら、そのユーザーの新しい認証セッションが開始されます。

attemptメソッドは、認証が成功すればtrueを返します。失敗時はfalseを返します。

リダイレクタのintendedメソッドは、認証フィルターで引っかかる前にアクセスしようとしていたURLへ、ユーザーをリダイレクトしてくれます。そのリダイレクトが不可能な場合の移動先として、フォールバックURIをこのメソッドに指定してください。

追加条件の指定

お望みであれば、ユーザーのメールアドレスとパスワードに付け加え、認証時のクエリに追加の条件を指定することも可能です。例として、ユーザーが「アクティブ」である条件を追加してみましょう。

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
    // ユーザーは存在しており、かつアクティブで、資格停止されていない
}

Note: この例のように、emailを必ず認証に使用しなくてならない訳ではありません。データーベース中にあるユーザー名(username)に該当する、一意にユーザーを特定できるカラムであれば何でも使用できます。

特定のGuardインスタンスへのアクセス

Authファサードのguardメソッドにより、使用したいガードインスタンスを指定できます。これによりまったく異なった認証用のモデルやユーザーテーブルを使い、アプリケーションの別々の部分に対する認証が管理できます。

guardメソッドへ渡すガード名は、auth.php認証ファイルのguards設定の一つと対応している必要があります。

if (Auth::guard('admin')->attempt($credentials)) {
    //
}

ログアウト

アプリケーションからユーザーをログアウトさせるには、Authファサードのlogoutメソッドを使用してください。これはユーザーセッションの認証情報をクリアします。

Auth::logout();

継続ログイン

アプリケーションでログイン維持(Remember me)機能を持たせたい場合は、attemptメソッドの第2引数に論理値を指定します。ユーザーが自分でログアウトしない限り、認証を無期限に保持します。"remember me"トークンを保存するために使用する文字列のremember_tokenカラムをusersテーブルに持たせる必要があります。

if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
    // このメンバーは継続ログインされる
}

この機能を使用している時に、ユーザーが"remember me"クッキーを使用して認証されているかを判定するには、viaRememberメソッドを使用します。

if (Auth::viaRemember()) {
    //
}

他の認証方法

Userインスタンスによる認証

既存ユーザーインスタンスをアプリケーションへログインさせたい場合、そのユーザーインスタンスのloginメソッドを呼び出します。指定オブジェクトはIlluminate\Contracts\Auth\Authenticatable契約を実装しておく必要があります。LaravelのApp\Models\Userモデルは、このインターフェイスを始めから実装しています。この認証方法は、ユーザーがアプリケーションに登録した直後など、すでに有効なユーザーインスタンスがある場合に役立ちます。

Auth::login($user);

// 指定したユーザーでログインし、"remember"にする
Auth::login($user, true);

使用したいガードインスタンスを指定することもできます。

Auth::guard('admin')->login($user);

IDによるユーザー認証

ユーザーをアプリケーションへIDによりログインさせる場合は、loginUsingIdメソッドを使います。このメソッドは認証させたいユーザーの主キーを引数に受け取ります。

Auth::loginUsingId(1);

// 指定したユーザーでログインし、"remember"にする
Auth::loginUsingId(1, true);

ユーザーを一度だけ認証する

onceメソッドを使用すると、アプリケーションにユーザーをそのリクエストの間だけログインさせることができます。セッションもクッキーも使用しないため、ステートレスなAPIを構築する場合に便利です。

if (Auth::once($credentials)) {
    //
}

HTTP基本認証

HTTP基本認証により、専用の「ログイン」ページを用意しなくても手っ取り早くアプリケーションにユーザーをログインさせられます。これを使用するには、ルートにauth.basicミドルウェアを付けてください。auth.basicミドルウェアはLaravelフレームワークに含まれているので、定義する必要はありません。

Route::get('profile', function() {
    // 認証済みのユーザーのみが入れる
})->middleware('auth.basic');

ミドルウェアをルートに指定すれば、ブラウザからこのルートへアクセスされると自動的に認証が求められます。デフォルトでは、auth.basicミドルウェアはユーザーを決める"username"としてユーザーのemailカラムを使用します。

FastCGIの注意

PHP FastCGIを使用している場合、初期状態のままでHTTP基本認証は正しく動作しないでしょう。以下の行を.htaccessファイルへ追加してください。

RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

ステートレスなHTTP基本認証

セッションの識別クッキーを用いずにHTTP基本認証を使用することもできます。これはとくにAPI認証に便利です。実装するには、onceBasicメソッドを呼び出すミドルウェアを定義してください。onceBasicメソッドが何もレスポンスを返さなかった場合、リクエストをアプリケーションの先の処理へ通します。

<?php

namespace App\Http\Middleware;

use Illuminate\Support\Facades\Auth;

class AuthenticateOnceWithBasicAuth
{
    /**
     * 送信されたリクエストの処理
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, $next)
    {
        return Auth::onceBasic() ?: $next($request);
    }

}

次にルートミドルウェアを登録し、ルートに付加します。

Route::get('api/user', function() {
    // 認証済みのユーザーのみが入れる
})->middleware('auth.basic.once');

ログアウト

アプリケーションからユーザーをログアウトさせる場合、Authファサードのlogoutメソッドを使用してください。これにより、ユーザーセッションの認証情報はクリアされます。

use Illuminate\Support\Facades\Auth;

Auth::logout();

他のデバイス上のセッションを無効化

さらにLaravelは現在のユーザーの現在のデバイス上のセッションを無効化せずに、他のデバイス上のセッションを無効化し、「ログアウト」させるメカニズムを提供しています。通常この機能は、ユーザーがパスワードを変更した場合に現在のデバイスの認証を保持したまま、他のデバイスのセッションを切断したいときに便利でしょう。

これを使用するには、app/Http/Kernel.phpクラスのwebミドルウェアグループ中に、Illuminate\Session\Middleware\AuthenticateSessionミドルウェアが存在し、コメントを確実に外してください。

'web' => [
    // ...
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    // ...
],

それから、AuthファサードのlogoutOtherDevicesメソッドを使用してください。このメソッドは、入力フォームからアプリケーションが受け取る、現在のパスワードを引数に渡す必要があります。

use Illuminate\Support\Facades\Auth;

Auth::logoutOtherDevices($password);

logoutOtherDevicesメソッドが起動すると、ユーザーの他のセッションはすべて無効になります。つまり、以前に認証済みのすべてのガードが「ログアウト」されます。

Note: loginルートに対するルート名をカスタマイズしながら、AuthenticateSessionミドルウェアを使用している場合は、アプリケーションの例外ハンドラにあるunauthenticatedメソッドをオーバーライドし、ログインページへユーザーを確実にリダイレクトしてください。

カスタムガードの追加

独自の認証ガードはAuthファサードのextendメソッドを使用し、定義します。サービスプロバイダの中で呼び出します。AuthServiceProviderをLaravelはあらかじめ用意しているので、この中にコードを設置できます。

<?php

namespace App\Providers;

use App\Services\Auth\JwtGuard;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * サービスの初期起動後の登録実行
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Auth::extend('jwt', function($app, $name, array $config) {
            // Illuminate\Contracts\Auth\Guardのインスタンスを返す

            return new JwtGuard(Auth::createUserProvider($config['provider']));
        });
    }
}

上記の例のように、コールバックをextendメソッドに渡し、Illuminate\Contracts\Auth\Guardの実装を返します。このインスタンスは、カスタムガードで定義が必要ないくつかのメソッドを持っています。カスタムガードを定義したら、auth.php設定ファイルの、guards設定で使用できます。

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

クロージャリクエストガード

HTTPリクエストをベースとした、カスタム認証システムを実装する一番簡単な方法は、Auth::viaRequestメソッドを使用する方法です。このメソッドは一つのクロージャの中で、認証プロセスを素早く定義できるように用意しています。

利用するにはAuthServiceProviderbootメソッドの中から、Auth::viaRequestメソッドを呼び出してください。viaRequestメソッドの最初の引数は、認証ドライバ名です。名前にはカスタムガードを表す文字列を何でも使用できます。メソッド2つ目の引数は、受信したHTTPリクエストを受け取り、ユーザーインスタンスか認証失敗時のnullを返すクロージャを指定します。

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

/**
 * 全認証/認可サービスの登録
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Auth::viaRequest('custom-token', function ($request) {
        return User::where('token', $request->token)->first();
    });
}

カスタム認証ドライバーを定義したら、auth.php設定ファイルのguards設定で、そのドライバを利用します。

'guards' => [
    'api' => [
        'driver' => 'custom-token',
    ],
],

カスタムユーザープロバイダの追加

ユーザー情報を保管するために伝統的なリレーショナルデータベースを使用したくなければ、Laravelに独自の認証ユーザープロバイダを拡張する必要があります。Authファサードのproviderメソッドを使い、カスタムユーザープロバイダを定義します。

<?php

namespace App\Providers;

use App\Extensions\RiakUserProvider;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * サービスの初期起動後の登録実行
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Auth::provider('riak', function($app, array $config) {
            // Illuminate\Contracts\Auth\UserProviderのインスタンスを返す

            return new RiakUserProvider($app->make('riak.connection'));
        });
    }
}

providerメソッドでプロバイダを登録したら、auth.php設定ファイルで新しいユーザープロバイダへ切り替えます。最初に、新しいドライバを使用するproviderを定義します。

'providers' => [
    'users' => [
        'driver' => 'riak',
    ],
],

次に、このプロバイダをguards設定項目で利用します。

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
],

ユーザープロバイダ契約

Illuminate\Contracts\Auth\UserProviderは、MySQLやRiakなどのような持続性のストレージシステムに対するIlluminate\Contracts\Auth\Authenticatableの実装を取得することだけに責任を持っています。これらの2つのインターフェイスはユーザーデータがどのように保存されているか、それを表すのがどんなタイプのクラスなのかにかかわらず、認証メカニズムを機能し続けるために役立っています。

Illuminate\Contracts\Auth\UserProvider契約を見てみましょう。

<?php

namespace Illuminate\Contracts\Auth;

interface UserProvider
{
    public function retrieveById($identifier);
    public function retrieveByToken($identifier, $token);
    public function updateRememberToken(Authenticatable $user, $token);
    public function retrieveByCredentials(array $credentials);
    public function validateCredentials(Authenticatable $user, array $credentials);
}

retrieveById関数は、通常MySQLデータベースの自動増分IDのようなユーザーを表すキーを受け付けます。IDにマッチするAuthenticatable実装が取得され、返されます。

retrieveByToken関数は、一意の$identifierremember_tokenフィールドに保存されている"remember me" $tokenからユーザーを取得します。前のメソッドと同じく、Authenticatable実装が返されます。

updateRememberTokenメソッドは、$userremember_tokenフィールドを新しい$tokenで更新します。真新しいトークンは、"remember me"ログインの試みに成功するか、そのユーザーがログアウトしたときにアサインされます。

retrieveByCredentialsメソッドはアプリケーションへのログイン時に、Auth::attemptメソッドに指定するのと同じユーザー認証情報の配列を引数に取ります。メソッドは裏で動作する持続ストレージにより、認証情報に一致するユーザーを「クエリ」する必要があります。典型的な使用法の場合、このメソッドは$credentials['username']の"where"条件でクエリを実行するでしょう。メソッドはAuthenticatableの実装を返します。このメソッドはパスワードバリデーションや認証を行ってはいけません

validateCredentialsメソッドは指定された$userと、そのユーザーを認証するための$credentialsとを比較します。たとえば、このメソッドで$user->getAuthPassword()の値と$credentials['password']Hash::checkにより値を比較します。このメソッドは、パスワードが有効であるかを示すtruefalseだけを返します。

Authenticatable契約

これでUserProviderの各メソッドが明らかになりました。続いてAuthenticatable契約を見てみましょう。プロバイダはretrieveByIdretrieveByTokenretrieveByCredentialsメソッドでこのインターフェイスの実装を返していたことを思い出してください。

<?php

namespace Illuminate\Contracts\Auth;

interface Authenticatable
{
    public function getAuthIdentifierName();
    public function getAuthIdentifier();
    public function getAuthPassword();
    public function getRememberToken();
    public function setRememberToken($value);
    public function getRememberTokenName();
}

このインターフェイスはシンプルです。getAuthIdentifierNameメソッドは、ユーザーの「主キー」フィールドの名前を返します。getAuthIdentifierメソッドはユーザーの主キーを返します。MySQLを裏で使用している場合、これは自動増分される主キーでしょう。getAuthPasswordはユーザーのハッシュ済みのパスワードを返します。このインターフェイスはどのORMや抽象ストレージ層を使用しているかにかかわらず、どんなUserクラスに対しても認証システムが動作するようにしてくれています。デフォルトでLaravelはappディレクトリ中に、このインターフェイスを実装してるUserクラスを持っています。ですから実装例として、このクラスを調べてみてください。

イベント

Laravelは認証処理の過程で、さまざまなイベントを発行します。EventServiceProviderの中で、こうしたイベントに対するリスナを設定できます。:

/**
 * アプリケーションに指定されたイベントリスナ
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Auth\Events\Registered' => [
        'App\Listeners\LogRegisteredUser',
    ],

    'Illuminate\Auth\Events\Attempting' => [
        'App\Listeners\LogAuthenticationAttempt',
    ],

    'Illuminate\Auth\Events\Authenticated' => [
        'App\Listeners\LogAuthenticated',
    ],

    'Illuminate\Auth\Events\Login' => [
        'App\Listeners\LogSuccessfulLogin',
    ],

    'Illuminate\Auth\Events\Failed' => [
        'App\Listeners\LogFailedLogin',
    ],

    'Illuminate\Auth\Events\Validated' => [
        'App\Listeners\LogValidated',
    ],

    'Illuminate\Auth\Events\Verified' => [
        'App\Listeners\LogVerified',
    ],

    'Illuminate\Auth\Events\Logout' => [
        'App\Listeners\LogSuccessfulLogout',
    ],

    'Illuminate\Auth\Events\CurrentDeviceLogout' => [
        'App\Listeners\LogCurrentDeviceLogout',
    ],

    'Illuminate\Auth\Events\OtherDeviceLogout' => [
        'App\Listeners\LogOtherDeviceLogout',
    ],

    'Illuminate\Auth\Events\Lockout' => [
        'App\Listeners\LogLockout',
    ],

    'Illuminate\Auth\Events\PasswordReset' => [
        'App\Listeners\LogPasswordReset',
    ],
];

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる