メインコンテンツまでスキップ

認証

はじめに

多くのWebアプリケーションは、ユーザーがアプリケーションに認証し「ログイン」する方法を提供しています。Webアプリケーションでこの機能を実装することは複雑で、潜在的にリスクのある取り組みとなる可能性があります。そのため、Laravelは、認証を迅速かつ安全かつ簡単に実装するために必要なツールを提供することを目指しています。

基本的に、Laravelの認証機能は「ガード」と「プロバイダ」で構成されています。ガードは、各リクエストでユーザーが認証される方法を定義します。たとえば、Laravelには、セッションストレージとクッキーを使用して状態を維持する session ガードが付属しています。

プロバイダは、永続的なストレージからユーザーを取得する方法を定義します。Laravel には、Eloquent やデータベースクエリビルダーを使用してユーザーを取得するサポートが付属しています。ただし、必要に応じてアプリケーションに追加のプロバイダを定義することができます。

アプリケーションの認証構成ファイルは config/auth.php にあります。このファイルには、Laravel の認証サービスの動作を調整するためのいくつかのよく文書化されたオプションが含まれています。

注記

ガードとプロバイダは、"ロール" と "権限" とは混同すべきではありません。権限を使用してユーザーアクションを承認する方法について詳しく知りたい場合は、認可 ドキュメントを参照してください。

スターターキット

すぐに始めたいですか?新しい Laravel アプリケーションに Laravel アプリケーションスターターキット をインストールしてください。データベースをマイグレーションした後、ブラウザを /register またはアプリケーションに割り当てられた他の URL に移動します。スターターキットが、認証システム全体の骨組みを構築するのを手伝ってくれます!

最終的な Laravel アプリケーションでスターターキットを使用しないことを選択しても、Laravel Breeze スターターキットをインストールすることは、実際の Laravel プロジェクトで Laravel の認証機能をすべて実装する方法を学ぶ素晴らしい機会です。 Laravel Breeze は認証コントローラー、ルート、ビューを作成するため、これらのファイル内のコードを調べて、Laravel の認証機能がどのように実装されるかを学ぶことができます。

データベースに関する考慮事項

デフォルトでは、Laravel には app/Models ディレクトリに App\Models\UserEloquent モデル が含まれています。このモデルは、デフォルトの Eloquent 認証ドライバーと共に使用できます。Eloquent を使用していない場合は、Laravel クエリビルダーを使用する database 認証プロバイダーを使用できます。

App\Models\User モデルのデータベーススキーマを構築する際には、パスワード列が少なくとも 60 文字の長さであることを確認してください。もちろん、新しい Laravel アプリケーションに含まれる users テーブルのマイグレーションは、この長さを超える列を既に作成しています。

また、users(または同等の)テーブルに、100文字のnullableな文字列remember_tokenカラムが含まれていることを確認する必要があります。このカラムは、アプリケーションにログインする際に「ログイン状態を保持する」オプションを選択したユーザーのトークンを格納するために使用されます。新しいLaravelアプリケーションに含まれるデフォルトのusersテーブルマイグレーションには、このカラムが既に含まれています。

エコシステムの概要

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

まず、認証がどのように機能するかを考えてみましょう。Webブラウザを使用する場合、ユーザーはログインフォームを介してユーザー名とパスワードを提供します。これらの資格情報が正しい場合、アプリケーションは認証されたユーザーに関する情報をユーザーのセッションに保存します。ブラウザに発行されたクッキーにはセッションIDが含まれており、アプリケーションへの後続のリクエストは正しいセッションにユーザーを関連付けることができます。セッションクッキーを受け取った後、アプリケーションはセッションIDに基づいてセッションデータを取得し、認証情報がセッションに保存されていることを認識し、ユーザーを「認証済み」と見なします。

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

Laravelに組み込まれたブラウザ認証サービス

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

アプリケーションスターターキット

このドキュメントで説明されているように、これらの認証サービスと手動でやり取りして、アプリケーション独自の認証レイヤーを構築することができます。ただし、より迅速に始めるために、私たちは、全体の認証レイヤーの堅牢で現代的な足場を提供する無料のパッケージをリリースしています。これらのパッケージには、Laravel BreezeLaravel Jetstream、およびLaravel Fortifyが含まれています。

_Laravel Breeze_は、ログイン、登録、パスワードリセット、メール確認、パスワード確認など、Laravelのすべての認証機能のシンプルで最小限の実装です。Laravel Breezeのビューレイヤーは、Tailwind CSSでスタイル付けされたシンプルなBladeテンプレートで構成されています。始めるには、Laravelのアプリケーションスターターキットのドキュメントを参照してください。

_Laravel Fortify_は、Laravelのためのヘッドレス認証バックエンドであり、このドキュメントで見つかる多くの機能を実装しています。これには、クッキーベースの認証や、二要素認証、メール確認などの他の機能が含まれます。Fortifyは、Laravel Jetstreamの認証バックエンドを提供するか、Laravel Sanctumと組み合わせて、Laravelと認証が必要なSPAを認証するために独立して使用することができます。

_Laravel Jetstream_は、美しい、現代的なUIを備えたLaravel Fortifyの認証サービスを消費および公開する堅牢なアプリケーションスターターキットです。Tailwind CSSLivewire、および/またはInertiaによって動作します。Laravel Jetstreamには、二要素認証、チームサポート、ブラウザセッション管理、プロファイル管理、およびLaravel Sanctumとの組み込み統合をオプションでサポートしており、APIトークン認証を提供します。LaravelのAPI認証オファリングについては、以下で説明します。

LaravelのAPI認証サービス

Laravelには、APIトークンの管理やAPIトークンを使用したリクエストの認証を支援するための2つのオプションのパッケージが提供されています:PassportSanctum。これらのライブラリとLaravelの組み込みのクッキーベースの認証ライブラリは相互に排他的ではないことに注意してください。これらのライブラリは主にAPIトークン認証に焦点を当てており、一方、組み込みの認証サービスはクッキーベースのブラウザ認証に焦点を当てています。多くのアプリケーションは、Laravelの組み込みのクッキーベースの認証サービスとLaravelのAPI認証パッケージの1つを使用します。

Passport

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

Sanctum

OAuth2の複雑さと開発者の混乱に対応するために、私たちは、第一当事者のWebリクエストとAPIリクエストの両方を処理できるよりシンプルで効率的な認証パッケージを構築することを目指しました。この目標は、Laravel Sanctum のリリースによって実現され、第一当事者のWeb UIとAPIを提供するアプリケーションや、バックエンドのLaravelアプリケーションとは別に存在する単一ページアプリケーション(SPA)によって動作するアプリケーション、モバイルクライアントを提供するアプリケーションにおいて、優先されるべき推奨される認証パッケージと考えられるべきです。

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

Laravel Sanctumは、Laravel Jetstreamアプリケーションスターターキットに含めるAPIパッケージとして選択したものであり、Webアプリケーションの認証ニーズの大部分に最適だと考えています。

サマリーとスタックの選択

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

次に、サードパーティによって消費されるAPIを提供するアプリケーションの場合、アプリケーションのAPIトークン認証にはPassportまたはSanctumのいずれかを選択します。一般的には、Sanctumは可能な限り選択すべきです。なぜなら、API認証、SPA認証、モバイル認証に対応したシンプルで完全なソリューションであり、"スコープ"や"権限"のサポートも含まれているからです。

Laravelバックエンドで動作するシングルページアプリケーション(SPA)を構築している場合は、Laravel Sanctumを使用する必要があります。Sanctumを使用する場合は、バックエンド認証ルートを手動で実装するか、Laravel Fortifyを利用して、登録、パスワードリセット、メール確認などの機能のためのルートとコントローラを提供するヘッドレス認証バックエンドサービスを利用する必要があります。

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

そして、迅速に開始したい場合は、私たちがお勧めするLaravel Breezeを使用して、Laravelの組込み認証サービスとLaravel Sanctumのお気に入りの認証スタックをすでに使用している新しいLaravelアプリケーションを素早く開始する方法があります。

認証クイックスタート

警告

このドキュメントのこの部分では、Laravelアプリケーションスターターキットを介してユーザを認証する方法について説明しており、迅速に開始するためのUIスキャフォールディングが含まれています。直接Laravelの認証システムと統合したい場合は、ユーザの手動認証に関するドキュメントをご覧ください。

スターターキットのインストール

まず、Laravelアプリケーションのスターターキットをインストールする必要があります。 現在のスターターキットであるLaravel BreezeとLaravel Jetstreamは、新しいLaravelアプリケーションに認証を組み込むための美しくデザインされたスタートポイントを提供しています。

Laravel Breezeは、ログイン、登録、パスワードリセット、メール認証、パスワード確認など、Laravelのすべての認証機能の最小限のシンプルな実装です。 Laravel Breezeのビューレイヤーは、Tailwind CSSでスタイル付けされたシンプルなBladeテンプレートで構成されています。 さらに、BreezeはLivewireまたはInertiaに基づいたスキャフォールディングオプションを提供し、InertiaベースのスキャフォールディングにはVueまたはReactの使用を選択できます。

Laravel Jetstreamは、LivewireまたはInertiaとVueを使用してアプリケーションのスキャフォールディングをサポートするより堅牢なアプリケーションスターターキットです。 さらに、Jetstreamには、二要素認証、チーム、プロファイル管理、ブラウザーセッション管理、Laravel Sanctumを介したAPIサポート、アカウント削除などのオプションのサポートが含まれています。

認証されたユーザーの取得

認証スターターキットをインストールし、ユーザーがアプリケーションに登録して認証できるようにした後、しばしば現在の認証されたユーザーとやり取りする必要があります。 受信リクエストを処理する際、Authファサードのuserメソッドを介して認証されたユーザーにアクセスできます:

    use Illuminate\Support\Facades\Auth;

// Retrieve the currently authenticated user...
$user = Auth::user();

// Retrieve the currently authenticated user's ID...
$id = Auth::id();

また、ユーザーが認証されると、Illuminate\Http\Requestインスタンスを介して認証されたユーザーにアクセスできます。 リクエストのuserメソッドを介してアプリケーション内の任意のコントローラーメソッドから便利に認証されたユーザーにアクセスできるようにするために、Illuminate\Http\Requestオブジェクトを型ヒントすることを忘れないでください。

    <?php

namespace App\Http\Controllers;

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

class FlightController extends Controller
{
/**
* Update the flight information for an existing flight.
*/
public function update(Request $request): RedirectResponse
{
$user = $request->user();

// ...

return redirect('/flights');
}
}

現在のユーザーが認証されているかを判定する

着信 HTTP リクエストを行っているユーザーが認証されているかどうかを判定するには、Auth ファサードの check メソッドを使用できます。このメソッドは、ユーザーが認証されている場合に true を返します:

    use Illuminate\Support\Facades\Auth;

if (Auth::check()) {
// The user is logged in...
}
注記

check メソッドを使用してユーザーが認証されているかを判定することは可能ですが、通常はユーザーが特定のルート/コントローラにアクセスする前にユーザーが認証されていることを確認するためにミドルウェアを使用します。詳細については、ルートの保護のドキュメントを参照してください。

ルートの保護

ルートミドルウェアを使用して、認証されたユーザーのみが特定のルートにアクセスできるようにすることができます。Laravel には auth ミドルウェアが付属しており、これは Illuminate\Auth\Middleware\Authenticate クラスのミドルウェアエイリアスです。このミドルウェアは Laravel によって内部的に既にエイリアスされているため、ルート定義にミドルウェアをアタッチするだけで済みます:

    Route::get('/flights', function () {
// Only authenticated users may access this route...
})->middleware('auth');

認証されていないユーザーのリダイレクト

auth ミドルウェアが認証されていないユーザーを検出すると、ユーザーを login 名前付きルートにリダイレクトします。この動作を変更するには、アプリケーションの bootstrap/app.php ファイルの redirectGuestsTo メソッドを使用できます:

    use Illuminate\Http\Request;

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

// Using a closure...
$middleware->redirectGuestsTo(fn (Request $request) => route('login'));
})

ガードの指定

ルートに auth ミドルウェアをアタッチする際、ユーザーの認証に使用するべき「ガード」を指定することもできます。指定されたガードは、auth.php 構成ファイルの guards 配列のキーのいずれかに対応する必要があります:

    Route::get('/flights', function () {
// Only authenticated users may access this route...
})->middleware('auth:admin');

ログインのスロットリング

Laravel Breeze または Laravel Jetstream スターターキットを使用している場合、ログイン試行に対して自動的にレート制限が適用されます。デフォルトでは、ユーザーは正しい資格情報を提供できない場合、複数回の試行後に1分間ログインできなくなります。スロットリングはユーザーのユーザー名/メールアドレスとIPアドレスに固有です。

注記

アプリケーション内の他のルートのレート制限を設定したい場合は、レート制限のドキュメントをご覧ください。

ユーザーの手動認証

Laravelのアプリケーションスターターキットに含まれる認証用のスキャフォールディングを使用する必要はありません。このスキャフォールディングを使用しない場合は、Laravelの認証クラスを直接使用してユーザー認証を管理する必要があります。心配しないでください、簡単です!

Auth ファサードを介してLaravelの認証サービスにアクセスするために、クラスの先頭にAuthファサードをインポートする必要があります。次に、attemptメソッドを確認しましょう。attemptメソッドは通常、アプリケーションの「ログイン」フォームからの認証試行を処理するために使用されます。認証が成功した場合は、ユーザーのセッションを再生成してセッション固定を防止する必要があります:

    <?php

namespace App\Http\Controllers;

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

class LoginController extends Controller
{
/**
* Handle an authentication attempt.
*/
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メソッドは、最初の引数としてキー/値のペアの配列を受け取ります。配列内の値は、データベーステーブル内のユーザーを検索するために使用されます。したがって、上記の例では、email列の値でユーザーが取得されます。ユーザーが見つかった場合、データベースに保存されているハッシュ化されたパスワードが、配列を介してメソッドに渡されたpassword値と比較されます。フレームワークは、データベース内のハッシュ化されたパスワードと比較する前に、受信リクエストのpassword値を自動的にハッシュ化するため、受信リクエストのpassword値をハッシュ化してはいけません。2つのハッシュ化されたパスワードが一致した場合、ユーザーの認証セッションが開始されます。

Laravelの認証サービスは、認証ガードの「プロバイダー」構成に基づいてデータベースからユーザーを取得します。デフォルトのconfig/auth.php構成ファイルでは、Eloquentユーザープロバイダーが指定され、ユーザーを取得する際にApp\Models\Userモデルを使用するように指示されています。アプリケーションのニーズに基づいて、この構成ファイル内の値を変更することができます。


`attempt` メソッドは、認証が成功した場合に `true` を返します。それ以外の場合は `false` が返されます。

Laravel のリダイレクタが提供する `intended` メソッドは、ユーザーを認証ミドルウェアによって遮断される前にアクセスしようとしていた URL にリダイレクトします。意図した宛先が利用できない場合には、このメソッドにフォールバック URI を指定することができます。

<a name="specifying-additional-conditions"></a>
#### 追加条件の指定

必要であれば、ユーザーのメールアドレスとパスワードに加えて、認証クエリに追加のクエリ条件を追加することができます。これを行うには、`attempt` メソッドに渡される配列にクエリ条件を追加するだけです。たとえば、ユーザーが "active" とマークされていることを確認できます:

```php
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// Authentication was successful...
}

複雑なクエリ条件の場合、クロージャを資格情報の配列に提供することができます。このクロージャはクエリインスタンスで呼び出され、アプリケーションのニーズに基づいてクエリをカスタマイズすることができます:

    use Illuminate\Database\Eloquent\Builder;

if (Auth::attempt([
'email' => $email,
'password' => $password,
fn (Builder $query) => $query->has('activeSubscription'),
])) {
// Authentication was successful...
}
警告

これらの例では、email は必須のオプションではありません。これは単なる例として使用されています。データベーステーブルで "username" に対応する列名を使用する必要があります。

attemptWhen メソッドは、第二引数としてクロージャを受け取り、ユーザーを実際に認証する前に潜在的なユーザーをより詳細に検査するために使用できます。このクロージャは潜在的なユーザーを受け取り、ユーザーを認証できるかどうかを示すために true または false を返す必要があります:

    if (Auth::attemptWhen([
'email' => $email,
'password' => $password,
], function (User $user) {
return $user->isNotBanned();
})) {
// Authentication was successful...
}

特定のガードインスタンスへのアクセス

Auth ファサードの guard メソッドを介して、ユーザーの認証時に使用するガードインスタンスを指定することができます。これにより、完全に異なる認証可能なモデルやユーザーテーブルを使用して、アプリケーションの異なる部分の認証を管理することができます。

guard メソッドに渡されるガード名は、auth.php 構成ファイルで構成されたガードの1つに対応する必要があります:

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

ユーザーの記憶

多くのWebアプリケーションは、ログインフォームに「私を覚えておく」のチェックボックスを提供しています。アプリケーションで「私を覚えておく」機能を提供したい場合は、attemptメソッドの第2引数としてブール値を渡すことができます。

この値がtrueの場合、Laravelはユーザーを自動的に認証し続けるか、手動でログアウトするまで認証を維持します。usersテーブルには、「私を覚えておく」トークンを保存するために使用されるremember_token列が含まれている必要があります。新しいLaravelアプリケーションに含まれるusersテーブルのマイグレーションには、この列が既に含まれています:

    use Illuminate\Support\Facades\Auth;

if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
// The user is being remembered...
}

アプリケーションが「私を覚えておく」機能を提供している場合は、viaRememberメソッドを使用して、現在認証されているユーザーが「私を覚えておく」クッキーを使用して認証されたかどうかを判断できます:

    use Illuminate\Support\Facades\Auth;

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

その他の認証方法

ユーザーインスタンスの認証

既存のユーザーインスタンスを現在の認証ユーザーとして設定する必要がある場合は、Authファサードのloginメソッドにユーザーインスタンスを渡すことができます。指定されたユーザーインスタンスは、Illuminate\Contracts\Auth\Authenticatable contractの実装である必要があります。Laravelに含まれるApp\Models\Userモデルは、既にこのインターフェースを実装しています。この認証方法は、すでに有効なユーザーインスタンスを持っている場合、例えばユーザーがアプリケーションに登録した直後などに便利です:

    use Illuminate\Support\Facades\Auth;

Auth::login($user);

loginメソッドに第2引数としてブール値を渡すことができます。この値は、認証セッションに「私を覚えておく」機能が必要かどうかを示します。覚えておくということは、セッションが無期限に認証されるか、ユーザーがアプリケーションから手動でログアウトするまで維持されることを意味します:

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

必要に応じて、loginメソッドを呼び出す前に認証ガードを指定することができます。

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

IDによるユーザー認証

ユーザーをデータベースレコードの主キーを使用して認証するには、loginUsingIdメソッドを使用できます。このメソッドは、認証したいユーザーの主キーを受け入れます:

    Auth::loginUsingId(1);

loginUsingIdメソッドの第2引数としてブール値を渡すことができます。この値は、認証されたセッションに「記憶しておく」機能が必要かどうかを示します。これは、セッションが無期限に認証されるか、ユーザーがアプリケーションから手動でログアウトするまで続くことを意味します:

    Auth::loginUsingId(1, $remember = true);

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

単一のリクエストでアプリケーションとユーザーを認証するには、onceメソッドを使用できます。このメソッドを呼び出すときには、セッションやクッキーは使用されません:

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

HTTPベーシック認証

HTTPベーシック認証は、専用の「ログイン」ページを設定せずにアプリケーションのユーザーを簡単に認証する方法を提供します。始めるには、auth.basic ミドルウェアをルートにアタッチします。auth.basicミドルウェアはLaravelフレームワークに含まれているため、それを定義する必要はありません:

    Route::get('/profile', function () {
// Only authenticated users may access this route...
})->middleware('auth.basic');

ミドルウェアがルートにアタッチされると、ブラウザでそのルートにアクセスすると自動的に資格情報を求められます。デフォルトでは、auth.basicミドルウェアはusersデータベーステーブルのemail列をユーザーの「ユーザー名」として想定します。

FastCGIに関する注意事項

PHP FastCGIとApacheを使用してLaravelアプリケーションを提供している場合、HTTPベーシック認証が正常に機能しないことがあります。これらの問題を修正するには、次の行をアプリケーションの.htaccessファイルに追加できます:

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

状態を持たないHTTPベーシック認証

HTTPベーシック認証を使用して、セッションにユーザー識別子クッキーを設定せずにも利用できます。これは、アプリケーションの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
{
/**
* Handle an incoming request.
*
* @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 () {
// Only authenticated users may access this route...
})->middleware(AuthenticateOnceWithBasicAuth::class);

ログアウト

アプリケーションからユーザーを手動でログアウトするには、Auth ファサードが提供する logout メソッドを使用できます。これにより、ユーザーのセッションから認証情報が削除され、その後のリクエストは認証されません。

logout メソッドを呼び出すだけでなく、ユーザーのセッションを無効にし、CSRF トークン を再生成することが推奨されています。ユーザーをログアウトした後は、通常、ユーザーをアプリケーションのルートにリダイレクトします:

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

/**
* Log the user out of the application.
*/
public function logout(Request $request): RedirectResponse
{
Auth::logout();

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

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

return redirect('/');
}

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

Laravel は、ユーザーが現在のデバイスのセッションを無効にすることなく、他のデバイスでアクティブなセッションを無効にして「ログアウト」するメカニズムも提供しています。この機能は、ユーザーがパスワードを変更または更新する際に、現在のデバイスを認証したまま他のデバイスのセッションを無効にしたい場合に通常利用されます。

始める前に、セッション認証を受けるべきルートに Illuminate\Session\Middleware\AuthenticateSession ミドルウェアが含まれていることを確認する必要があります。通常、このミドルウェアは、アプリケーションのほとんどのルートに適用できるように、ルートグループ定義に配置することが推奨されます。デフォルトでは、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には、このプロセスを簡単にするための組み込みのミドルウェアが用意されています。この機能を実装するには、ユーザーにパスワードの確認を求めるビューを表示するための1つのルートと、パスワードが有効であることを確認し、ユーザーを意図した場所にリダイレクトするための別のルートを定義する必要があります。

注記

以下のドキュメントでは、Laravelのパスワード確認機能との統合方法について直接説明しています。ただし、より迅速に開始したい場合は、Laravelアプリケーションスターターキットにはこの機能のサポートが含まれています!

設定

パスワードを確認した後、ユーザーは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;
use Illuminate\Support\Facades\Redirect;

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 フィールドが、認証されたユーザーのパスワードと実際に一致するかどうかが決定されます。パスワードが有効な場合、Laravel のセッションにユーザーがパスワードを確認したことを通知する必要があります。passwordConfirmed メソッドは、ユーザーのセッションにタイムスタンプを設定し、Laravel がユーザーが最後にパスワードを確認した時刻を判断するために使用できます。最後に、ユーザーを意図した目的地にリダイレクトできます。

ルートの保護

最近のパスワード確認が必要なアクションを実行する任意のルートには、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
{
// ...

/**
* Bootstrap any application services.
*/
public function boot(): void
{
Auth::extend('jwt', function (Application $app, string $name, array $config) {
// Return an instance of 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つのクロージャを使用して認証プロセスを迅速に定義することができます。

始めるには、アプリケーションのAppServiceProviderbootメソッド内でAuth::viaRequestメソッドを呼び出します。viaRequestメソッドは、最初の引数として認証ドライバーの名前を受け入れます。この名前は、カスタムガードを説明する任意の文字列である必要があります。メソッドに渡される2番目の引数は、着信HTTPリクエストを受け取り、ユーザーインスタンスを返すか、認証に失敗した場合はnullを返すクロージャであるべきです:

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

/**
* Bootstrap any application services.
*/
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
{
// ...

/**
* Bootstrap any application services.
*/
public function boot(): void
{
Auth::provider('mongo', function (Application $app, array $config) {
// Return an instance of 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',
],
],

ユーザープロバイダ契約

Illuminate\Contracts\Auth\UserProviderの実装は、MySQL、MongoDBなどの永続ストレージシステムからIlluminate\Contracts\Auth\Authenticatableの実装を取得する責任があります。これらの2つのインターフェースにより、ユーザーデータの保存方法や認証されたユーザーを表すために使用されるクラスの種類に関係なく、Laravelの認証メカニズムが引き続き機能するようになります。```

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);
public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false);
}

retrieveById 関数は通常、ユーザーを表すキーを受け取ります。たとえば、MySQL データベースからの自動インクリメント ID などです。ID に一致する Authenticatable 実装は、このメソッドによって取得および返却されるべきです。

retrieveByToken 関数は、ユーザーを一意の $identifier と "remember me" $token で取得します。通常、remember_token のようなデータベースカラムに格納されます。前述のメソッドと同様に、一致するトークン値を持つ Authenticatable 実装は、このメソッドによって返却されるべきです。

updateRememberToken メソッドは、$user インスタンスの remember_token を新しい $token で更新します。成功した "remember me" 認証試行時やユーザーがログアウトしたときに、ユーザーに新しいトークンが割り当てられます。

retrieveByCredentials メソッドは、アプリケーションで認証を試みるときに Auth::attempt メソッドに渡される資格情報の配列を受け取ります。その後、このメソッドは、これらの資格情報に一致するユーザーを持続的なストレージから "クエリ" するべきです。通常、このメソッドは、$credentials['username'] の値に一致する "username" を持つユーザーレコードを検索する "where" 条件でクエリを実行します。このメソッドは、Authenticatable の実装を返却すべきです。このメソッドは、パスワードの検証や認証を試みてはいけません。

validateCredentials メソッドは、与えられた $user$credentials を比較してユーザーを認証します。たとえば、このメソッドは通常、Hash::check メソッドを使用して、$user->getAuthPassword() の値を $credentials['password'] の値と比較します。このメソッドは、パスワードが有効かどうかを示す true または false を返却すべきです。

rehashPasswordIfRequired メソッドは、必要に応じて与えられた $user のパスワードを再ハッシュするべきです。たとえば、このメソッドは通常、Hash::needsRehash メソッドを使用して、$credentials['password'] の値を再ハッシュする必要があるかどうかを判断します。パスワードを再ハッシュする必要がある場合、このメソッドは Hash::make メソッドを使用してパスワードを再ハッシュし、ユーザーのレコードを持続的なストレージ内で更新すべきです。

認証可能な契約

UserProvider の各メソッドを探索したので、Authenticatable 契約を見てみましょう。ユーザープロバイダーは、retrieveByIdretrieveByTokenretrieveByCredentials メソッドからこのインターフェースの実装を返すべきです。

    <?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 メソッドはユーザーのハッシュ化されたパスワードを返すべきです。

このインターフェースにより、どの ORM やストレージ抽象化レイヤーを使用しているかに関係なく、認証システムが任意の「ユーザー」クラスと連携できます。デフォルトでは、Laravel には app/Models ディレクトリに含まれる App\Models\User クラスがこのインターフェースを実装しています。

パスワードの自動再ハッシュ

Laravel のデフォルトのパスワードハッシュアルゴリズムは bcrypt です。bcrypt ハッシュの「ワークファクター」は、アプリケーションの config/hashing.php 設定ファイルや BCRYPT_ROUNDS 環境変数を介して調整できます。

通常、CPU / GPU 処理能力が向上するにつれて bcrypt ワークファクターを増やすべきです。アプリケーションの bcrypt ワークファクターを増やすと、Laravel はユーザーが Laravel のスターターキットを介してアプリケーションに認証するか、attempt メソッドを介してユーザーを手動で認証する際に、ユーザーパスワードを優雅かつ自動的に再ハッシュします。

通常、自動パスワード再ハッシュはアプリケーションに影響を与えることはありませんが、hashing 設定ファイルを公開してこの動作を無効にすることができます:

php artisan config:publish hashing

設定ファイルを公開したら、rehash_on_login 設定値を false に設定できます。

'rehash_on_login' => false,

イベント

Laravelは認証プロセス中にさまざまなイベントをディスパッチします。以下のイベントに対してリスナーを定義することができます。

イベント名
Illuminate\Auth\Events\Registered
Illuminate\Auth\Events\Attempting
Illuminate\Auth\Events\Authenticated
Illuminate\Auth\Events\Login
Illuminate\Auth\Events\Failed
Illuminate\Auth\Events\Validated
Illuminate\Auth\Events\Verified
Illuminate\Auth\Events\Logout
Illuminate\Auth\Events\CurrentDeviceLogout
Illuminate\Auth\Events\OtherDeviceLogout
Illuminate\Auth\Events\Lockout
Illuminate\Auth\Events\PasswordReset