ログインのしくみ(認証)
ログイン(認証)のしくみとして、ガードとプロバイダ、ログイン中のユーザーの取り出し、ルートの保護、手動のログイン・ログアウト、パスワードの再確認を説明します。
多くのアプリには、「ログイン」して使う機能があります。認証とは、「あなたはだれか」を確かめることです。ログインの機能を自分で作るのは、むずかしく、まちがえると危険です。そこで 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 メソッドで取り出せます。
use Illuminate\Support\Facades\Auth;
// ログイン中のユーザーを取り出す
$user = Auth::user();
// ログイン中のユーザーの ID を取り出す
$id = Auth::id();
また、Illuminate\Http\Request の user メソッドでも取り出せます。コントローラーのメソッドの引数に、型(Request)を書いておけば、Laravel が自動で渡してくれます。
<?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 を返します。
use Illuminate\Support\Facades\Auth;
if (Auth::check()) {
// ユーザーはログインしている
}
補足
check でも調べられますが、ふつうは、ルートやコントローラーに入る前に、ミドルウェア(リクエストが処理に届く前に、間に入って確かめる処理)でログインを確かめます。次の「ルートを保護する」を見てください。
ルートを保護する#
ログインしたユーザーだけが使えるルート(URL と処理を結びつけたもの)にしたいときは、ルートのミドルウェアを使います。Laravel には、Illuminate\Auth\Middleware\Authenticate クラスの別名(短い呼び名)として、auth ミドルウェアが最初から用意されています。ルートに付けるだけです。
Route::get('/flights', function () {
// ログインしたユーザーだけが使える
})->middleware('auth');
ログインしていない人の行き先#
auth ミドルウェアは、ログインしていない人を、login という名前のルートへ転送します。変えたいときは、bootstrap/app.php の redirectGuestsTo を使います。
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 を使います。
use Illuminate\Http\Request;
->withMiddleware(function (Middleware $middleware): void {
$middleware->redirectUsersTo('/panel');
// クロージャで決める場合
$middleware->redirectUsersTo(fn (Request $request) => route('panel'));
})
ガードを指定する#
auth ミドルウェアを付けるとき、どのガードで認証するかも指定できます。名前は、auth.php の guards 配列のキーのどれかにします。
Route::get('/flights', function () {
// ログインした管理者だけが使える
})->middleware('auth:admin');
ログインの回数制限#
スターターキットを使っていると、ログインしようとする回数に、自動で制限(レート制限)がかかります。何度か正しくない情報を入れると、最初は1分間ログインできなくなります。制限は、ユーザー名(メールアドレス)と IP アドレス(ネットにつながる機器ごとの番号)の組ごとに数えます。
補足
アプリのほかのルートにも回数の制限をかけたいときは、回数の制限のページを見てください。
ユーザーを手動で認証する#
スターターキットの認証の雛形を、必ず使わなければならないわけではありません。使わないなら、Laravel の認証のクラスを直接使って、認証を作ります。むずかしくありません。
認証の機能は、Auth ファサードから使います。クラスの先頭で Auth を use で読み込んでおきます。ここでは、ログインのフォームの送信を処理する attempt メソッドを見ましょう。認証に成功したら、セッション固定攻撃(他人が用意したセッション ID でログインさせる攻撃)を防ぐため、セッションの ID を作り直します。
<?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 に渡す配列に足すだけです。たとえば、「有効」なユーザーだけを認証します。
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// 認証に成功した
}
複雑な条件は、配列にクロージャを入れて書きます。クロージャは、クエリを受け取ります。
use Illuminate\Database\Eloquent\Builder;
if (Auth::attempt([
'email' => $email,
'password' => $password,
fn (Builder $query) => $query->has('activeSubscription'),
])) {
// 認証に成功した
}
注意
これらの例で email は、例として使っているだけで、必須ではありません。自分の表で「ユーザー名」にあたる列の名前を使ってください。
attemptWhen は、第2引数にクロージャを取ります。本当に認証する前に、ユーザーをもっと細かく調べられます。クロージャはユーザーを受け取り、認証してよければ true、だめなら false を返します。
if (Auth::attemptWhen([
'email' => $email,
'password' => $password,
], function (User $user) {
return $user->isNotBanned();
})) {
// 認証に成功した
}
特定のガードを使う#
Auth ファサードの guard メソッドで、どのガードを使うかを指定できます。アプリの部分ごとに、別々のユーザーのモデルや表で認証を管理できます。
guard に渡す名前は、auth.php で設定したガードのどれかにします。
if (Auth::guard('admin')->attempt($credentials)) {
// ...
}
ログインしたままにする(Remember me)#
ログインのフォームに、「ログインしたままにする」のチェックを付けたいときは、attempt の第2引数に、真偽値(true か false)を渡します。
true なら、ユーザーが自分でログアウトするまで、ずっとログインしたままになります。users の表には、このための文字列の remember_token 列が必要です(新しいアプリの表には、最初から入っています)。
use Illuminate\Support\Facades\Auth;
if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
// ユーザーを覚えておく
}
「ログインしたままにする」を使えるようにしているなら、viaRemember で、いまのユーザーがその Cookie でログインしたかを調べられます。
use Illuminate\Support\Facades\Auth;
if (Auth::viaRemember()) {
// ...
}
そのほかの認証のしかた#
ユーザーのインスタンスで認証する#
すでに手元にあるユーザー(インスタンス)を、ログイン中にしたいときは、Auth ファサードの login に渡します。ユーザーは、Illuminate\Contracts\Auth\Authenticatable というコントラクト(決まった形の約束事)を実装している(約束どおりのメソッドを持っている)必要があります。App\Models\User は、最初から実装しています。たとえば、ユーザーが登録した直後のように、有効なユーザーがすでに手元にあるときに役立ちます。
use Illuminate\Support\Facades\Auth;
Auth::login($user);
第2引数に真偽値を渡すと、「ログインしたままにする」にするかを決められます。
Auth::login($user, $remember = true);
ガードを指定してから login を呼ぶこともできます。
Auth::guard('admin')->login($user);
ID で認証する#
データベースの行の主キーでユーザーを認証するには、loginUsingId を使います。
Auth::loginUsingId(1);
remember の引数に真偽値を渡すと、「ログインしたままにする」にするかを決められます。
Auth::loginUsingId(1, remember: true);
1回だけ認証する#
once を使うと、1回のリクエストだけ、ユーザーを認証します。セッションも Cookie も使わず、Login イベント(「ログインした」という知らせ)も出ません。
if (Auth::once($credentials)) {
// ...
}
HTTP Basic 認証#
HTTP Basic 認証は、ログインのページを用意せずに、手早くユーザーを認証する方法です。ルートに auth.basic ミドルウェアを付けます。Laravel に最初から入っているので、定義は要りません。
Route::get('/profile', function () {
// ログインしたユーザーだけが使える
})->middleware('auth.basic');
付けると、ブラウザでそのルートを開いたときに、自動でユーザー名とパスワードを聞かれます。ふつう auth.basic は、users の表の email 列を「ユーザー名」とみなします。
FastCGI を使うときの注意#
Apache(Web サーバーのソフト)で PHP FastCGI(PHP を動かす方式の1つ)を使っているときは、HTTP Basic 認証が正しく動かないことがあります。次の2行を、アプリの .htaccess に足すと、直せることがあります。
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
セッションを使わない HTTP Basic 認証#
セッションにユーザーを覚える Cookie を置かずに、HTTP Basic 認証を使うこともできます。API のリクエストを HTTP 認証で認証したいときに役立ちます。onceBasic を呼ぶミドルウェアを作ります。onceBasic がレスポンスを返さなければ、リクエストを先へ進めます。
<?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);
}
}
あとは、ルートにそのミドルウェアを付けます。
Route::get('/api/user', function () {
// ログインしたユーザーだけが使える
})->middleware(AuthenticateOnceWithBasicAuth::class);
ログアウトする#
手動でログアウトさせるには、Auth ファサードの logout を使います。セッションから認証の情報が消え、次のリクエストからは、ログインしていない扱いになります。
logout に加えて、セッションを無効にし、CSRF トークンを作り直すことがすすめられています。ログアウトしたあとは、ふつう、アプリのトップへ転送します。
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 という別名で付けられます。
Route::middleware(['auth', 'auth.session'])->group(function () {
Route::get('/', function () {
// ...
});
});
そのうえで、Auth ファサードの logoutOtherDevices を呼びます。ユーザーに、いまのパスワードをもう一度入れてもらう必要があります。入力のフォームで受け取ってください。
use Illuminate\Support\Facades\Auth;
Auth::logoutOtherDevices($currentPassword);
logoutOtherDevices を呼ぶと、ほかのセッションは完全に無効になり、それまでに認証されていたすべてのガードからログアウトされます。
パスワードの再確認#
アプリによっては、ある操作の前や、大事な場所へ進む前に、もう一度パスワードを確かめたいことがあります。Laravel には、そのためのミドルウェアが最初から入っています。ルートを2つ作ります。1つは、パスワードの確認を求める画面を出すルート、もう1つは、パスワードが正しいかを確かめて、元の行き先へ転送するルートです。
補足
ここでは、パスワードの再確認の機能を直接使う方法を説明します。早く始めたいなら、スターターキットにこの機能が入っています。
設定#
パスワードを確かめたユーザーは、3時間は、もう一度聞かれません。この時間は、config/auth.php の password_timeout で変えられます。
ルート#
パスワードの確認フォーム#
まず、パスワードの確認を求めるビューを出すルートです。
Route::get('/confirm-password', function () {
return view('auth.confirm-password');
})->middleware('auth')->name('password.confirm');
このビューには、password の入力欄のあるフォームを置きます。「大事な場所に入るので、パスワードの確認が必要です」のような説明を書いてもかまいません。
パスワードを確かめる#
次に、確認のフォームの送信を受けるルートを作ります。パスワードが正しいかを確かめ、元の行き先へ転送します。
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 という名前のルートへ転送します。
Route::get('/settings', function () {
// ...
})->middleware(['password.confirm']);
Route::post('/settings', function () {
// ...
})->middleware(['password.confirm']);
自分のガードを作る#
Auth ファサードの extend で、自分のガードを作れます。extend は、サービスプロバイダ(アプリの起動のときに道具を登録する場所)の中で呼びます。Laravel には最初から AppServiceProvider があるので、そこに書けます。
<?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 で使えます。
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
クロージャで作るガード#
HTTP リクエストをもとにした認証を、いちばん簡単に作るには、Auth::viaRequest を使います。クロージャ1つで、認証のしかたを決められます。
アプリの AppServiceProvider の boot の中で Auth::viaRequest を呼びます。第1引数は、認証ドライバの名前で、自分のガードを表す好きな文字列にできます。第2引数は、リクエストを受け取り、ユーザーを返すクロージャです。認証できなければ null を返します。
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 に、ドライバとして設定します。
'guards' => [
'api' => [
'driver' => 'custom-token',
],
],
最後に、認証のミドルウェアをルートに付けるときに、そのガードを指定します。
Route::middleware('auth:api')->group(function () {
// ...
});
自分のユーザープロバイダを作る#
ユーザーを、ふつうのリレーショナルデータベース(表でデータを持つデータベース)に保存していないなら、自分のユーザープロバイダで Laravel を拡張します。Auth ファサードの provider を使います。プロバイダを作る関数は、Illuminate\Contracts\Auth\UserProvider の実装を返します。
<?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 を定義します。
'providers' => [
'users' => [
'driver' => 'mongo',
],
],
最後に、guards で、そのプロバイダを指定します。
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
UserProvider の約束事#
Illuminate\Contracts\Auth\UserProvider の実装は、MySQL や MongoDB のような保存先から、Illuminate\Contracts\Auth\Authenticatable の実装を取り出す役目を持ちます。この2つのインターフェイスのおかげで、ユーザーの保存先や、ユーザーを表すクラスが何であっても、Laravel の認証は動き続けられます。
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);
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
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 にコピーします)。
php artisan config:publish hashing
公開したら、rehash_on_login を false にします。
'rehash_on_login' => false,
ハッシュについては、ハッシュのページも見てください。
イベント#
認証のあいだに、Laravel はいろいろなイベント(「〜が起きた」という知らせ)を出します。どれにも、リスナー(知らせを受けて動く処理)を作れます。次のイベントは、どれも Illuminate\Auth\Events の名前空間にあります。
| イベント | 説明(名前の意味) |
|---|---|
Registered |
登録された |
Attempting |
認証を試みている |
Authenticated |
認証された |
Login |
ログインした |
Failed |
認証に失敗した |
Validated |
検証された |
Verified |
メールアドレスが確認された |
Logout |
ログアウトした |
CurrentDeviceLogout |
いまの端末がログアウトした |
OtherDeviceLogout |
ほかの端末がログアウトした |
Lockout |
ロックアウトされた |
PasswordReset |
パスワードが再設定された |
PasswordResetLinkSent |
パスワードの再設定のリンクが送られた |
関連するページ#
公式ドキュメント(英語)
2026年10月5日時点の内容をもとに、日本語でまとめています。