本文へ移動
Laravel Tips

ログインのしくみ(認証)

ログイン(認証)のしくみとして、ガードとプロバイダ、ログイン中のユーザーの取り出し、ルートの保護、手動のログイン・ログアウト、パスワードの再確認を説明します。

多くのアプリには、「ログイン」して使う機能があります。認証とは、「あなたはだれか」を確かめることです。ログインの機能を自分で作るのは、むずかしく、まちがえると危険です。そこで Laravel は、安全で手早く認証を作れる道具を用意しています。

Laravel の認証は、ガードとプロバイダでできています。ガードは「リクエストごとに、ユーザーをどう確かめるか」を決めます。たとえば session ガードは、セッション(同じ人のアクセスをまたいで情報を覚えておくしくみ)と Cookie(ブラウザに保存される小さなデータ)を使って、ログインの状態を覚えておきます。プロバイダは、「ユーザーを、保存している場所からどう取り出すか」を決めます。Eloquent(モデルのしくみ)と、データベースのクエリビルダ(SQL を書かずに問い合わせるしくみ)から取り出す方法が、最初から入っています。必要なら自分で足せます。

認証の設定は config/auth.php にあります。設定の意味は、ファイルの中にくわしく書かれています。

補足

ガードとプロバイダは、「役割」や「権限」とはちがいます。ユーザーに何をさせてよいかを決める話は、認可のページにあります。

最初から認証を作ってもらう(スターターキット)#

早く始めたいなら、新しい Laravel アプリにスターターキット(最初から画面や機能がそろった雛形)を入れます。データベースのマイグレーション(表を作る手順書)を実行したあと、ブラウザで /register などを開けば、認証の一式ができています。

最終的にスターターキットを使わないとしても、入れてみる価値があります。認証のコントローラー・ルート・ビューが入っているので、中のコードを読めば、Laravel の認証機能の使い方を実際の例で学べます。

データベースについて#

Laravel には、最初から app/Models に App\Models\User(Eloquent のモデル)が入っています。標準の Eloquent の認証ドライバ(認証の方式)で使えます。

Eloquent を使わないアプリなら、クエリビルダを使う database のプロバイダが使えます。MongoDB を使うアプリは、MongoDB の公式の Laravel 用ユーザー認証のドキュメントを見てください。

App\Models\User の表を作るときは、パスワードの列を60文字以上にします。新しい Laravel アプリのマイグレーションは、すでにこれより長い列を作ります。

また、users の表(にあたる表)には、100文字の、空でもよい文字列の remember_token という列が必要です。ログインのときに「ログインしたままにする」を選んだユーザーのために、トークン(合言葉のような値)を入れる列です。これも、新しいアプリのマイグレーションに入っています。

認証まわりのパッケージの全体像#

Laravel には、認証に関わるパッケージがいくつかあります。まず、認証がどう動くかを整理します。

ブラウザでは、ユーザーがログインのフォームにユーザー名とパスワードを入れます。正しければ、アプリは「だれがログインしたか」をセッションに入れます。ブラウザには、セッション ID の入った Cookie が渡されます。次のリクエストからは、この Cookie のセッション ID でセッションを探し、ログイン済みと分かるので、「認証されたユーザー」として扱います。

ほかのサービスが API(データを受け渡す窓口)を使うときは、ブラウザがないので、ふつう Cookie は使えません。代わりに、リクエストのたびに API トークンを送ります。アプリは、そのトークンが有効かを調べて、トークンに結びついたユーザーによるリクエストとして扱います。

最初から入っているブラウザ向けの認証#

Laravel には、認証とセッションの機能が最初から入っています。ふつう Auth と Session のファサード(Auth::user() のように、クラス名と :: で機能を呼べる窓口)を通して使います。ブラウザからのリクエストを、Cookie で認証するための機能です。ユーザー名とパスワードの確かめ、ログイン、セッションへの保存、セッションの Cookie を渡すところまで、してくれます。

自分で認証の仕組みを組み立てることもできますが、早く始めたいなら、無料のスターターキットが、認証まわりの一式を用意してくれます。

API 向けの認証#

API のトークンを扱うために、あとから足せるパッケージが2つあります。Passport と Sanctum です。どちらも、最初から入っている Cookie の認証といっしょに使えます。Passport と Sanctum は API トークンの認証が中心で、最初から入っているほうは、ブラウザでの Cookie の認証が中心です。多くのアプリは、両方を使います。

Passport

OAuth2(ほかのサービスに、ログインの許可を渡す国際的な決まり)の認証を使えるようにするパッケージです。いろいろな種類のトークンを出せる、強力で複雑な API 認証の道具です。ただ、ほとんどのアプリは、OAuth2 の複雑な機能までは必要としません。また、SPA(1つのページで動くアプリ)やスマートフォンアプリの認証が、これまで分かりにくいという声がありました。

Sanctum

Laravel Sanctum は、OAuth2 の複雑さを避けるために作られた、もっと単純な認証パッケージです。ブラウザからの自社の画面のリクエストと、トークンによる API のリクエストの両方を扱えます。自社の画面と API の両方を出すアプリ、バックエンド(サーバー側のプログラム)とは別の SPA で動くアプリ、スマートフォン向けのアプリには、Sanctum がおすすめです。

Sanctum は、リクエストを受けると、まずセッションの Cookie でログインしているかを、Laravel の最初から入っている認証で調べます。Cookie で認証できなければ、次に API トークンを探し、あればそのトークンで認証します。

どれを選ぶか#

  • ブラウザで使う、1つにまとまった Laravel アプリなら、最初から入っている認証を使います
  • 第三者が使う API を出すなら、Passport か Sanctum を選びます。単純な Sanctum は、API 認証・SPA の認証・スマートフォンの認証に使え、「スコープ」(権限の範囲)にも対応しています。選べるなら Sanctum がおすすめです
  • Laravel のバックエンドで動く SPA を作るなら、Sanctum を使います。そのとき、ログインのルートを自分で作る(あとの「ユーザーを手動で認証する」を見てください)か、Laravel Fortify(画面を持たない認証のバックエンド。登録・パスワードの再設定・メールの確認のルートとコントローラーを用意する)を使います
  • OAuth2 の機能がすべて必要なら、Passport を選びます。AI のクライアントが使う MCP サーバー(AI に道具を渡す窓口)を作るなら、MCP のクライアントは OAuth での認証を求めるので、Passport を使います
  • 早く始めたいなら、最初から入っている認証を使ったスターターキットがおすすめです

認証のクイックスタート#

注意

ここからの説明は、スターターキットを入れた前提です(画面の雛形も入っています)。Laravel の認証を直接使うなら、あとの「ユーザーを手動で認証する」を見てください。

スターターキットを入れる#

まず、スターターキットを入れます。新しい Laravel アプリに認証を入れるための、よい出発点になります。

ログイン中のユーザーを取り出す#

スターターキットで作ったアプリで、ユーザーが登録・ログインできるようになったら、いまログインしているユーザーを使う場面が出てきます。リクエストの処理中は、Auth ファサードの user メソッドで取り出せます。

php
use Illuminate\Support\Facades\Auth;

// ログイン中のユーザーを取り出す
$user = Auth::user();

// ログイン中のユーザーの ID を取り出す
$id = Auth::id();

また、Illuminate\Http\Request の user メソッドでも取り出せます。コントローラーのメソッドの引数に、型(Request)を書いておけば、Laravel が自動で渡してくれます。

php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class FlightController extends Controller
{
    /**
     * 既存のフライトの情報を更新する
     */
    public function update(Request $request): RedirectResponse
    {
        $user = $request->user();

        // ...

        return redirect('/flights');
    }
}

ログインしているかを調べる#

リクエストしたユーザーがログインしているかを調べるには、Auth ファサードの check メソッドを使います。ログイン中なら true を返します。

php
use Illuminate\Support\Facades\Auth;

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

補足

check でも調べられますが、ふつうは、ルートやコントローラーに入る前に、ミドルウェア(リクエストが処理に届く前に、間に入って確かめる処理)でログインを確かめます。次の「ルートを保護する」を見てください。

ルートを保護する#

ログインしたユーザーだけが使えるルート(URL と処理を結びつけたもの)にしたいときは、ルートのミドルウェアを使います。Laravel には、Illuminate\Auth\Middleware\Authenticate クラスの別名(短い呼び名)として、auth ミドルウェアが最初から用意されています。ルートに付けるだけです。

php
Route::get('/flights', function () {
    // ログインしたユーザーだけが使える
})->middleware('auth');

ログインしていない人の行き先#

auth ミドルウェアは、ログインしていない人を、login という名前のルートへ転送します。変えたいときは、bootstrap/app.php の redirectGuestsTo を使います。

php
use Illuminate\Http\Request;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->redirectGuestsTo('/login');

    // クロージャ(名前のない関数)で決める場合
    $middleware->redirectGuestsTo(fn (Request $request) => route('login'));
})

ログイン済みの人の行き先#

guest ミドルウェアは、すでにログインしている人を、dashboard か home という名前のルートへ転送します。変えたいときは、bootstrap/app.php の redirectUsersTo を使います。

php
use Illuminate\Http\Request;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->redirectUsersTo('/panel');

    // クロージャで決める場合
    $middleware->redirectUsersTo(fn (Request $request) => route('panel'));
})

ガードを指定する#

auth ミドルウェアを付けるとき、どのガードで認証するかも指定できます。名前は、auth.php の guards 配列のキーのどれかにします。

php
Route::get('/flights', function () {
    // ログインした管理者だけが使える
})->middleware('auth:admin');

ログインの回数制限#

スターターキットを使っていると、ログインしようとする回数に、自動で制限(レート制限)がかかります。何度か正しくない情報を入れると、最初は1分間ログインできなくなります。制限は、ユーザー名(メールアドレス)と IP アドレス(ネットにつながる機器ごとの番号)の組ごとに数えます。

補足

アプリのほかのルートにも回数の制限をかけたいときは、回数の制限のページを見てください。

ユーザーを手動で認証する#

スターターキットの認証の雛形を、必ず使わなければならないわけではありません。使わないなら、Laravel の認証のクラスを直接使って、認証を作ります。むずかしくありません。

認証の機能は、Auth ファサードから使います。クラスの先頭で Auth を use で読み込んでおきます。ここでは、ログインのフォームの送信を処理する attempt メソッドを見ましょう。認証に成功したら、セッション固定攻撃(他人が用意したセッション ID でログインさせる攻撃)を防ぐため、セッションの ID を作り直します。

php
<?php

namespace App\Http\Controllers;

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

class LoginController extends Controller
{
    /**
     * ログインの試行を処理する
     */
    public function authenticate(Request $request): RedirectResponse
    {
        $credentials = $request->validate([
            'email' => ['required', 'email'],
            'password' => ['required'],
        ]);

        if (Auth::attempt($credentials)) {
            $request->session()->regenerate();

            return redirect()->intended('dashboard');
        }

        return back()->withErrors([
            'email' => 'The provided credentials do not match our records.',
        ])->onlyInput('email');
    }
}

attempt の第1引数は、キーと値の組の配列です。この値を使って、データベースの表からユーザーを探します。上の例では、email の列の値でユーザーを探します。見つかったら、データベースにあるハッシュ(元に戻せない形に変えた値)のパスワードと、配列の password の値を比べます。リクエストの password を、自分でハッシュにしてはいけません。 フレームワークが自動でハッシュにしてから比べます。2つが一致すれば、そのユーザーのログインのセッションが始まります。

Laravel は、ガードの「プロバイダ」の設定に従って、データベースからユーザーを探します。最初の config/auth.php では、Eloquent のプロバイダが指定され、App\Models\User のモデルを使うようになっています。アプリに合わせて変えられます。

attempt は、認証に成功すると true を、そうでなければ false を返します。

リダイレクター(別の URL へ転送する道具)の intended メソッドは、ユーザーが最初に開こうとしていた URL へ転送します。認証のミドルウェアに止められる前の行き先です。その行き先が使えないときのために、代わりの行き先(URI)を渡せます。

追加の条件を付ける#

メールアドレスとパスワードのほかにも、認証の検索に条件を足せます。attempt に渡す配列に足すだけです。たとえば、「有効」なユーザーだけを認証します。

php
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
    // 認証に成功した
}

複雑な条件は、配列にクロージャを入れて書きます。クロージャは、クエリを受け取ります。

php
use Illuminate\Database\Eloquent\Builder;

if (Auth::attempt([
    'email' => $email,
    'password' => $password,
    fn (Builder $query) => $query->has('activeSubscription'),
])) {
    // 認証に成功した
}

注意

これらの例で email は、例として使っているだけで、必須ではありません。自分の表で「ユーザー名」にあたる列の名前を使ってください。

attemptWhen は、第2引数にクロージャを取ります。本当に認証する前に、ユーザーをもっと細かく調べられます。クロージャはユーザーを受け取り、認証してよければ true、だめなら false を返します。

php
if (Auth::attemptWhen([
    'email' => $email,
    'password' => $password,
], function (User $user) {
    return $user->isNotBanned();
})) {
    // 認証に成功した
}

特定のガードを使う#

Auth ファサードの guard メソッドで、どのガードを使うかを指定できます。アプリの部分ごとに、別々のユーザーのモデルや表で認証を管理できます。

guard に渡す名前は、auth.php で設定したガードのどれかにします。

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

ログインしたままにする(Remember me)#

ログインのフォームに、「ログインしたままにする」のチェックを付けたいときは、attempt の第2引数に、真偽値(true か false)を渡します。

true なら、ユーザーが自分でログアウトするまで、ずっとログインしたままになります。users の表には、このための文字列の remember_token 列が必要です(新しいアプリの表には、最初から入っています)。

php
use Illuminate\Support\Facades\Auth;

if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
    // ユーザーを覚えておく
}

「ログインしたままにする」を使えるようにしているなら、viaRemember で、いまのユーザーがその Cookie でログインしたかを調べられます。

php
use Illuminate\Support\Facades\Auth;

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

そのほかの認証のしかた#

ユーザーのインスタンスで認証する#

すでに手元にあるユーザー(インスタンス)を、ログイン中にしたいときは、Auth ファサードの login に渡します。ユーザーは、Illuminate\Contracts\Auth\Authenticatable というコントラクト(決まった形の約束事)を実装している(約束どおりのメソッドを持っている)必要があります。App\Models\User は、最初から実装しています。たとえば、ユーザーが登録した直後のように、有効なユーザーがすでに手元にあるときに役立ちます。

php
use Illuminate\Support\Facades\Auth;

Auth::login($user);

第2引数に真偽値を渡すと、「ログインしたままにする」にするかを決められます。

php
Auth::login($user, $remember = true);

ガードを指定してから login を呼ぶこともできます。

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

ID で認証する#

データベースの行の主キーでユーザーを認証するには、loginUsingId を使います。

php
Auth::loginUsingId(1);

remember の引数に真偽値を渡すと、「ログインしたままにする」にするかを決められます。

php
Auth::loginUsingId(1, remember: true);

1回だけ認証する#

once を使うと、1回のリクエストだけ、ユーザーを認証します。セッションも Cookie も使わず、Login イベント(「ログインした」という知らせ)も出ません。

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

HTTP Basic 認証#

HTTP Basic 認証は、ログインのページを用意せずに、手早くユーザーを認証する方法です。ルートに auth.basic ミドルウェアを付けます。Laravel に最初から入っているので、定義は要りません。

php
Route::get('/profile', function () {
    // ログインしたユーザーだけが使える
})->middleware('auth.basic');

付けると、ブラウザでそのルートを開いたときに、自動でユーザー名とパスワードを聞かれます。ふつう auth.basic は、users の表の email 列を「ユーザー名」とみなします。

FastCGI を使うときの注意#

Apache(Web サーバーのソフト)で PHP FastCGI(PHP を動かす方式の1つ)を使っているときは、HTTP Basic 認証が正しく動かないことがあります。次の2行を、アプリの .htaccess に足すと、直せることがあります。

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

セッションを使わない HTTP Basic 認証#

セッションにユーザーを覚える Cookie を置かずに、HTTP Basic 認証を使うこともできます。API のリクエストを HTTP 認証で認証したいときに役立ちます。onceBasic を呼ぶミドルウェアを作ります。onceBasic がレスポンスを返さなければ、リクエストを先へ進めます。

php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;

class AuthenticateOnceWithBasicAuth
{
    /**
     * 届いたリクエストを処理する
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        return Auth::onceBasic() ?: $next($request);
    }

}

あとは、ルートにそのミドルウェアを付けます。

php
Route::get('/api/user', function () {
    // ログインしたユーザーだけが使える
})->middleware(AuthenticateOnceWithBasicAuth::class);

ログアウトする#

手動でログアウトさせるには、Auth ファサードの logout を使います。セッションから認証の情報が消え、次のリクエストからは、ログインしていない扱いになります。

logout に加えて、セッションを無効にし、CSRF トークンを作り直すことがすすめられています。ログアウトしたあとは、ふつう、アプリのトップへ転送します。

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

/**
 * ユーザーをログアウトさせる
 */
public function logout(Request $request): RedirectResponse
{
    Auth::logout();

    $request->session()->invalidate();

    $request->session()->regenerateToken();

    return redirect('/');
}

ほかの端末のセッションを無効にする#

いま使っている端末のログインは残したまま、ほかの端末のセッションを無効にして「ログアウト」させる機能もあります。パスワードを変えたときに、ほかの端末をログアウトさせたい場合に役立ちます。

使う前に、セッションの認証を受けさせたいルートに、Illuminate\Session\Middleware\AuthenticateSession ミドルウェアが付いていることを確かめます。ふつう、ルートのグループにまとめて付け、アプリのほとんどのルートに効くようにします。最初から、auth.session という別名で付けられます。

php
Route::middleware(['auth', 'auth.session'])->group(function () {
    Route::get('/', function () {
        // ...
    });
});

そのうえで、Auth ファサードの logoutOtherDevices を呼びます。ユーザーに、いまのパスワードをもう一度入れてもらう必要があります。入力のフォームで受け取ってください。

php
use Illuminate\Support\Facades\Auth;

Auth::logoutOtherDevices($currentPassword);

logoutOtherDevices を呼ぶと、ほかのセッションは完全に無効になり、それまでに認証されていたすべてのガードからログアウトされます。

パスワードの再確認#

アプリによっては、ある操作の前や、大事な場所へ進む前に、もう一度パスワードを確かめたいことがあります。Laravel には、そのためのミドルウェアが最初から入っています。ルートを2つ作ります。1つは、パスワードの確認を求める画面を出すルート、もう1つは、パスワードが正しいかを確かめて、元の行き先へ転送するルートです。

補足

ここでは、パスワードの再確認の機能を直接使う方法を説明します。早く始めたいなら、スターターキットにこの機能が入っています。

設定#

パスワードを確かめたユーザーは、3時間は、もう一度聞かれません。この時間は、config/auth.php の password_timeout で変えられます。

ルート#

パスワードの確認フォーム#

まず、パスワードの確認を求めるビューを出すルートです。

php
Route::get('/confirm-password', function () {
    return view('auth.confirm-password');
})->middleware('auth')->name('password.confirm');

このビューには、password の入力欄のあるフォームを置きます。「大事な場所に入るので、パスワードの確認が必要です」のような説明を書いてもかまいません。

パスワードを確かめる#

次に、確認のフォームの送信を受けるルートを作ります。パスワードが正しいかを確かめ、元の行き先へ転送します。

php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

Route::post('/confirm-password', function (Request $request) {
    if (! Hash::check($request->password, $request->user()->password)) {
        return back()->withErrors([
            'password' => ['The provided password does not match our records.']
        ]);
    }

    $request->session()->passwordConfirmed();

    return redirect()->intended();
})->middleware(['auth', 'throttle:6,1']);

このルートを順に見ます。まず、リクエストの password が、ログイン中のユーザーのパスワードと一致するかを確かめます。正しければ、「パスワードを確認した」とセッションに伝えます。passwordConfirmed は、最後にパスワードを確認した時刻をセッションに入れます。最後に、元の行き先へ転送します。

ルートを保護する#

少し前にパスワードを確かめていないと使えない操作のルートには、password.confirm ミドルウェアを付けます。Laravel に最初から入っています。付けると、ユーザーの元の行き先をセッションに保存し、password.confirm という名前のルートへ転送します。

php
Route::get('/settings', function () {
    // ...
})->middleware(['password.confirm']);

Route::post('/settings', function () {
    // ...
})->middleware(['password.confirm']);

自分のガードを作る#

Auth ファサードの extend で、自分のガードを作れます。extend は、サービスプロバイダ(アプリの起動のときに道具を登録する場所)の中で呼びます。Laravel には最初から AppServiceProvider があるので、そこに書けます。

php
<?php

namespace App\Providers;

use App\Services\Auth\JwtGuard;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    // ...

    /**
     * アプリのサービスを起動する
     */
    public function boot(): void
    {
        Auth::extend('jwt', function (Application $app, string $name, array $config) {
            // Illuminate\Contracts\Auth\Guard を実装したものを返す

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

extend に渡すコールバック(あとで呼ばれる関数)は、Illuminate\Contracts\Auth\Guard の実装を返します。このインターフェイス(決まった形の約束事)にあるメソッドを作ることで、ガードができます。作ったガードは、auth.php の guards で使えます。

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

クロージャで作るガード#

HTTP リクエストをもとにした認証を、いちばん簡単に作るには、Auth::viaRequest を使います。クロージャ1つで、認証のしかたを決められます。

アプリの AppServiceProvider の boot の中で Auth::viaRequest を呼びます。第1引数は、認証ドライバの名前で、自分のガードを表す好きな文字列にできます。第2引数は、リクエストを受け取り、ユーザーを返すクロージャです。認証できなければ null を返します。

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

/**
 * アプリのサービスを起動する
 */
public function boot(): void
{
    Auth::viaRequest('custom-token', function (Request $request) {
        return User::where('token', (string) $request->token)->first();
    });
}

認証ドライバを作ったら、auth.php の guards に、ドライバとして設定します。

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

最後に、認証のミドルウェアをルートに付けるときに、そのガードを指定します。

php
Route::middleware('auth:api')->group(function () {
    // ...
});

自分のユーザープロバイダを作る#

ユーザーを、ふつうのリレーショナルデータベース(表でデータを持つデータベース)に保存していないなら、自分のユーザープロバイダで Laravel を拡張します。Auth ファサードの provider を使います。プロバイダを作る関数は、Illuminate\Contracts\Auth\UserProvider の実装を返します。

php
<?php

namespace App\Providers;

use App\Extensions\MongoUserProvider;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    // ...

    /**
     * アプリのサービスを起動する
     */
    public function boot(): void
    {
        Auth::provider('mongo', function (Application $app, array $config) {
            // Illuminate\Contracts\Auth\UserProvider を実装したものを返す

            return new MongoUserProvider($app->make('mongo.connection'));
        });
    }
}

provider で登録したら、auth.php で新しいプロバイダに切り替えます。まず、新しいドライバを使う provider を定義します。

php
'providers' => [
    'users' => [
        'driver' => 'mongo',
    ],
],

最後に、guards で、そのプロバイダを指定します。

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

UserProvider の約束事#

Illuminate\Contracts\Auth\UserProvider の実装は、MySQL や MongoDB のような保存先から、Illuminate\Contracts\Auth\Authenticatable の実装を取り出す役目を持ちます。この2つのインターフェイスのおかげで、ユーザーの保存先や、ユーザーを表すクラスが何であっても、Laravel の認証は動き続けられます。

UserProvider は、次のとおりです。

php
<?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);
    public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false);
}
メソッド 説明
retrieveById ユーザーを表すキー(MySQL の自動で増える ID など)を受け取り、合う Authenticatable を返す
retrieveByToken ユーザーの $identifier と「ログインしたままにする」の $token(ふつう remember_token の列)で、ユーザーを返す
updateRememberToken $user の remember_token を、新しい $token に更新する。「ログインしたままにする」の認証に成功したときと、ログアウトのときに、新しいトークンが入る
retrieveByCredentials Auth::attempt に渡された情報の配列を受け取り、その情報に合うユーザーを保存先から探して返す。このメソッドの中で、パスワードの確認や認証をしてはいけない
validateCredentials $user と $credentials を比べて、認証できるかを true か false で返す。ふつう Hash::check で、$user->getAuthPassword() と $credentials['password'] を比べる
rehashPasswordIfRequired 必要で、できるなら、$user のパスワードをハッシュし直す。ふつう Hash::needsRehash で必要かを調べ、必要なら Hash::make でハッシュし直して、保存先を更新する

Authenticatable の約束事#

次は、Authenticatable です。ユーザープロバイダは、retrieveById・retrieveByToken・retrieveByCredentials から、このインターフェイスの実装を返します。

php
<?php

namespace Illuminate\Contracts\Auth;

interface Authenticatable
{
    public function getAuthIdentifierName();
    public function getAuthIdentifier();
    public function getAuthPasswordName();
    public function getAuthPassword();
    public function getRememberToken();
    public function setRememberToken($value);
    public function getRememberTokenName();
}
メソッド 説明
getAuthIdentifierName ユーザーの「主キー」の列の名前を返す
getAuthIdentifier ユーザーの「主キー」の値を返す(MySQL なら、ふつう自動で増える主キー)
getAuthPasswordName パスワードの列の名前を返す
getAuthPassword ユーザーのハッシュにしたパスワードを返す
getRememberToken 「ログインしたままにする」のトークンを返す
setRememberToken 「ログインしたままにする」のトークンを設定する
getRememberTokenName 「ログインしたままにする」のトークンの列の名前を返す

このインターフェイスのおかげで、どんな ORM(データベースをクラスで扱うしくみ)や保存のしくみを使っていても、認証が動きます。Laravel には、最初から app/Models に、これを実装した App\Models\User が入っています。

パスワードの自動ハッシュ直し#

Laravel が標準で使うパスワードのハッシュの方式は bcrypt です。bcrypt の「作業係数」(ハッシュにかける手間の大きさ)は、config/hashing.php か、環境変数 BCRYPT_ROUNDS で変えられます。

パソコンの性能が上がるにつれ、作業係数は少しずつ上げていくのがふつうです。作業係数を上げると、スターターキットでの認証や、attempt での手動の認証のときに、ユーザーのパスワードが、自動でハッシュし直されます。

ふつう、自動のハッシュ直しがアプリのじゃまをすることはありません。止めたいときは、hashing の設定ファイルを公開します(自分のアプリの config にコピーします)。

bash
php artisan config:publish hashing

公開したら、rehash_on_login を false にします。

php
'rehash_on_login' => false,

ハッシュについては、ハッシュのページも見てください。

イベント#

認証のあいだに、Laravel はいろいろなイベント(「〜が起きた」という知らせ)を出します。どれにも、リスナー(知らせを受けて動く処理)を作れます。次のイベントは、どれも Illuminate\Auth\Events の名前空間にあります。

イベント 説明(名前の意味)
Registered 登録された
Attempting 認証を試みている
Authenticated 認証された
Login ログインした
Failed 認証に失敗した
Validated 検証された
Verified メールアドレスが確認された
Logout ログアウトした
CurrentDeviceLogout いまの端末がログアウトした
OtherDeviceLogout ほかの端末がログアウトした
Lockout ロックアウトされた
PasswordReset パスワードが再設定された
PasswordResetLinkSent パスワードの再設定のリンクが送られた

関連するページ#

公式ドキュメント(英語)

2026年10月5日時点の内容をもとに、日本語でまとめています。

ページの一覧