認証
- はじめに
- 認証クイックスタート
- ユーザーの手動認証
- HTTP基本認証
- ログアウト
- パスワード確認
- カスタムガードの追加
- カスタムユーザープロバイダーの追加
- 自動パスワード再ハッシュ
- ソーシャル認証
- イベント
はじめに
多くの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\User
Eloquentモデルをapp/Models
ディレクトリに含めています。このモデルは、デフォルトのEloquent認証ドライバーと一緒に使用できます。アプリケーションがEloquentを使用していない場合は、Laravelクエリビルダーを使用するdatabase
認証プロバイダーを使用できます。
また、`````users`````(または同等の)テーブルに、100文字のnullableな文字列`````remember_token`````列が含まれていることを確認する必要があります。この列は、アプリケーションにログインする際に「私を覚えておく」オプションを選択したユーザーのトークンを保存するために使用されます。再度、新しいLaravelアプリケーションに含まれるデフォルトの`````users`````テーブルマイグレーションには、すでにこの列が含まれています。
<a name="ecosystem-overview"></a>
### エコシステムの概要
Laravelは、認証に関連するいくつかのパッケージを提供しています。続行する前に、Laravelの一般的な認証エコシステムをレビューし、各パッケージの意図された目的について説明します。
まず、認証がどのように機能するかを考えてみましょう。Webブラウザを使用する場合、ユーザーはログインフォームを介してユーザー名とパスワードを提供します。これらの資格情報が正しい場合、アプリケーションは認証されたユーザーに関する情報をユーザーの[セッション](/read/laravel-11-x/f930b68e3eb7fc88.md)に保存します。ブラウザに発行されたクッキーには、セッションIDが含まれており、アプリケーションへの後続のリクエストは、ユーザーを正しいセッションに関連付けることができます。セッションクッキーが受信されると、アプリケーションはセッションIDに基づいてセッションデータを取得し、認証情報がセッションに保存されていることを確認し、ユーザーを「認証済み」と見なします。
リモートサービスがAPIにアクセスするために認証する必要がある場合、クッキーは通常、認証には使用されません。なぜなら、Webブラウザがないからです。代わりに、リモートサービスは各リクエストでAPIトークンをAPIに送信します。アプリケーションは、受信トークンを有効なAPIトークンのテーブルと照合し、そのAPIトークンに関連付けられたユーザーによってリクエストが「認証」されていると見なすことができます。
<a name="laravels-built-in-browser-authentication-services"></a>
#### Laravelの組み込みブラウザ認証サービス
Laravelには、通常`````Auth`````および`````Session`````ファサードを介してアクセスされる組み込みの認証およびセッションサービスが含まれています。これらの機能は、Webブラウザから開始されたリクエストに対してクッキーに基づく認証を提供します。ユーザーの資格情報を確認し、ユーザーを認証するためのメソッドを提供します。さらに、これらのサービスは、ユーザーのセッションに適切な認証データを自動的に保存し、ユーザーのセッションクッキーを発行します。これらのサービスの使用方法については、このドキュメントに記載されています。
**アプリケーションスターターキット**
このドキュメントで説明したように、これらの認証サービスと手動で対話して、アプリケーションの独自の認証レイヤーを構築できます。ただし、より迅速に開始できるように、全体の認証レイヤーの堅牢で現代的なスキャフォールディングを提供する[無料パッケージ](/read/laravel-11-x/4f3d9f3a392315aa.md)をリリースしました。これらのパッケージは、[Laravel Breeze](4f3d9f3a392315aa.md#laravel-breeze)、[Laravel Jetstream](4f3d9f3a392315aa.md#laravel-jetstream)、および[Laravel Fortify](/read/laravel-11-x/2037e1c83ee89144.md)です。
*Laravel Breeze*は、ログイン、登録、パスワードリセット、メール確認、パスワード確認を含むLaravelのすべての認証機能のシンプルで最小限の実装です。Laravel Breezeのビュー層は、[Tailwind CSS](https://tailwindcss.com)でスタイリングされたシンプルな[Bladeテンプレート](/read/laravel-11-x/3aaaf25bb396ee8c.md)で構成されています。始めるには、Laravelの[アプリケーションスターターキット](/read/laravel-11-x/4f3d9f3a392315aa.md)に関するドキュメントを確認してください。
*Laravel Fortify*は、Laravelのためのヘッドレス認証バックエンドであり、クッキーに基づく認証や二要素認証、メール確認などの機能を実装しています。Fortifyは、Laravel Jetstreamの認証バックエンドを提供するか、[Laravel Sanctum](/read/laravel-11-x/522811ea3cb9ffc5.md)と組み合わせて、Laravelと認証が必要なSPAの認証を提供するために独立して使用できます。
*[Laravel Jetstream](https://jetstream.laravel.com)*は、Laravel Fortifyの認証サービスを消費し、[Tailwind CSS](https://tailwindcss.com)、[Livewire](https://livewire.laravel.com)、および/または[Inertia](https://inertiajs.com)によって強化された美しい現代的なUIを持つ堅牢なアプリケーションスターターキットです。Laravel Jetstreamは、二要素認証、チームサポート、ブラウザセッション管理、プロファイル管理、APIトークン認証を提供するために[Laravel Sanctum](/read/laravel-11-x/522811ea3cb9ffc5.md)との統合を含むオプションのサポートを含んでいます。LaravelのAPI認証の提供については、以下で説明します。
<a name="laravels-api-authentication-services"></a>
#### LaravelのAPI認証サービス
Laravelは、APIトークンを管理し、APIトークンを使用して行われたリクエストを認証するのを支援するために、[Passport](/read/laravel-11-x/311471384a547295.md)と[Sanctum](/read/laravel-11-x/522811ea3cb9ffc5.md)の2つのオプションパッケージを提供しています。これらのライブラリとLaravelの組み込みのクッキーに基づく認証ライブラリは、相互排他的ではないことに注意してください。これらのライブラリは主にAPIトークン認証に焦点を当てており、組み込みの認証サービスはクッキーに基づくブラウザ認証に焦点を当てています。多くのアプリケーションは、Laravelの組み込みのクッキーに基づく認証サービスと、LaravelのAPI認証パッケージのいずれかを使用します。
**Passport**
Passportは、さまざまなOAuth2「グラントタイプ」を提供するOAuth2認証プロバイダーであり、さまざまなタイプのトークンを発行できます。一般的に、これはAPI認証のための堅牢で複雑なパッケージです。ただし、ほとんどのアプリケーションは、ユーザーや開発者にとって混乱を招く可能性のあるOAuth2仕様が提供する複雑な機能を必要としません。さらに、開発者は、PassportのようなOAuth2認証プロバイダーを使用してSPAアプリケーションやモバイルアプリケーションを認証する方法について歴史的に混乱していました。
**Sanctum**
OAuth2の複雑さと開発者の混乱に対応するために、私たちは、WebブラウザからのファーストパーティのWebリクエストとトークンを介したAPIリクエストの両方を処理できる、よりシンプルで合理化された認証パッケージを構築することを目指しました。この目標は、[Laravel Sanctum](/read/laravel-11-x/522811ea3cb9ffc5.md)のリリースによって実現され、ファーストパーティのWeb UIとAPIを提供するアプリケーション、またはバックエンドLaravelアプリケーションとは別に存在するSPA、またはモバイルクライアントを提供するアプリケーションに推奨される認証パッケージと見なされるべきです。
Laravel Sanctumは、アプリケーションの全認証プロセスを管理できるハイブリッドWeb/API認証パッケージです。これは、Sanctumベースのアプリケーションがリクエストを受信すると、Sanctumが最初にリクエストに認証されたセッションを参照するセッションクッキーが含まれているかどうかを判断するために行います。Sanctumは、前述のLaravelの組み込み認証サービスを呼び出すことでこれを実現します。リクエストがセッションクッキーを介して認証されていない場合、SanctumはリクエストにAPIトークンが含まれているかどうかを確認します。APIトークンが存在する場合、Sanctumはそのトークンを使用してリクエストを認証します。このプロセスについて詳しくは、Sanctumの[\
#### 要約とスタックの選択
要約すると、アプリケーションがブラウザを介してアクセスされ、モノリシックなLaravelアプリケーションを構築している場合、アプリケーションはLaravelの組み込み認証サービスを使用します。
次に、アプリケーションがサードパーティによって消費されるAPIを提供する場合、アプリケーションのAPIトークン認証を提供するために[Passport](/read/laravel-11-x/311471384a547295.md)または[Sanctum](/read/laravel-11-x/522811ea3cb9ffc5.md)のいずれかを選択します。一般的に、SanctumはAPI認証、SPA認証、モバイル認証のためのシンプルで完全なソリューションであり、「スコープ」や「能力」をサポートしているため、可能な限りSanctumを優先すべきです。
Laravelバックエンドによって動作するシングルページアプリケーション(SPA)を構築している場合は、[Laravel Sanctum](/read/laravel-11-x/522811ea3cb9ffc5.md)を使用する必要があります。Sanctumを使用する場合は、[手動で独自のバックエンド認証ルートを実装する](#authenticating-users)か、[Laravel Fortify](/read/laravel-11-x/2037e1c83ee89144.md)をヘッドレス認証バックエンドサービスとして利用し、登録、パスワードリセット、メール確認などの機能のためのルートとコントローラーを提供します。
Passportは、アプリケーションがOAuth2仕様によって提供されるすべての機能を絶対に必要とする場合に選択されることがあります。
また、迅速に始めたい場合は、[Laravel Breeze](4f3d9f3a392315aa.md#laravel-breeze)を推奨します。これは、Laravelの組み込み認証サービスとLaravel Sanctumの好ましい認証スタックをすでに使用している新しいLaravelアプリケーションを迅速に開始する方法です。
<a name="authentication-quickstart"></a>
## 認証クイックスタート
このドキュメントの部分では、[Laravelアプリケーションスターターキット](/read/laravel-11-x/4f3d9f3a392315aa.md)を介してユーザーを認証する方法について説明します。これには、迅速に開始するためのUIスキャフォールディングが含まれています。Laravelの認証システムと直接統合したい場合は、[手動でユーザーを認証する](#authenticating-users)ドキュメントを確認してください。
<a name="install-a-starter-kit"></a>
### スターターキットのインストール
まず、[Laravelアプリケーションスターターキット](/read/laravel-11-x/4f3d9f3a392315aa.md)をインストールする必要があります。現在のスターターキットであるLaravel BreezeとLaravel Jetstreamは、認証を新しいLaravelアプリケーションに組み込むための美しくデザインされた出発点を提供します。
Laravel Breezeは、ログイン、登録、パスワードリセット、メール確認、パスワード確認など、Laravelのすべての認証機能の最小限でシンプルな実装です。Laravel Breezeのビュー層は、[Bladeテンプレート](/read/laravel-11-x/3aaaf25bb396ee8c.md)で構成され、[Tailwind CSS](https://tailwindcss.com)でスタイリングされています。さらに、Breezeは[Livewire](https://livewire.laravel.com)または[Inertia](https://inertiajs.com)に基づくスキャフォールディングオプションを提供し、InertiaベースのスキャフォールディングにはVueまたはReactを使用する選択肢があります。
[Laravel Jetstream](https://jetstream.laravel.com)は、[Livewire](https://livewire.laravel.com)または[InertiaとVue](https://inertiajs.com)でアプリケーションをスキャフォールディングするためのサポートを含む、より堅牢なアプリケーションスターターキットです。さらに、Jetstreamは二要素認証、チーム、プロファイル管理、ブラウザセッション管理、[Laravel Sanctum](/read/laravel-11-x/522811ea3cb9ffc5.md)を介したAPIサポート、アカウント削除などのオプションサポートを提供します。
<a name="retrieving-the-authenticated-user"></a>
### 認証されたユーザーの取得
認証スターターキットをインストールし、ユーザーがアプリケーションに登録して認証できるようにした後、現在認証されているユーザーとやり取りする必要があることがよくあります。受信リクエストを処理している間、`````Auth`````ファサードの`````user`````メソッドを介して認証されたユーザーにアクセスできます:
``````php
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
インスタンスを介して認証されたユーザーにアクセスできます。型ヒントされたクラスは、コントローラーメソッドに自動的に注入されることを忘れないでください。Illuminate\Http\Request
オブジェクトを型ヒントすることで、アプリケーション内の任意のコントローラーメソッドからリクエストのuser
メソッドを介して認証されたユーザーに便利にアクセスできます:
<?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リクエストを行っているユーザーが認証されているかどうかを判断するには、check
メソッドをAuth
ファサードで使用できます。このメソッドは、ユーザーが認証されている場合に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'));
})
ガードの指定
``````php
Route::get('/flights', function () {
// Only authenticated users may access this route...
})->middleware('auth:admin');
`
ログインのスロットリング
Laravel BreezeまたはLaravel Jetstream スターターキットを使用している場合、ログイン試行に自動的にレート制限が適用されます。デフォルトでは、ユーザーは数回の試行の後に正しい資格情報を提供できなかった場合、1分間ログインできません。スロットリングは、ユーザーのユーザー名/メールアドレスとそのIPアドレスに固有です。
他のルートにレート制限を適用したい場合は、レート制限のドキュメントを確認してください。
ユーザーの手動認証
Laravelのアプリケーションスターターキットに含まれる認証スキャフォールディングを使用する必要はありません。このスキャフォールディングを使用しないことを選択した場合、Laravelの認証クラスを直接使用してユーザー認証を管理する必要があります。心配しないでください、それは簡単です!
Laravelの認証サービスにAuth
ファサードを介してアクセスしますので、クラスの先頭で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');
}
}
Laravelの認証サービスは、認証ガードの「プロバイダー」設定に基づいてデータベースからユーザーを取得します。デフォルトの`````config/auth.php`````設定ファイルでは、Eloquentユーザープロバイダーが指定されており、ユーザーを取得する際に`````App\Models\User`````モデルを使用するように指示されています。アプリケーションのニーズに基づいて、設定ファイル内でこれらの値を変更できます。
`````attempt`````メソッドは、認証が成功した場合に`````true`````を返します。そうでない場合は、`````false`````が返されます。
Laravelのリダイレクタによって提供される`````intended`````メソッドは、ユーザーが認証ミドルウェアによってインターセプトされる前にアクセスしようとしていたURLにユーザーをリダイレクトします。意図された宛先が利用できない場合、このメソッドにフォールバックURIを指定できます。
<a name="specifying-additional-conditions"></a>
#### 追加条件の指定
必要に応じて、ユーザーのメールアドレスとパスワードに加えて、認証クエリに追加のクエリ条件を追加することもできます。これを実現するために、`````attempt`````メソッドに渡される配列にクエリ条件を追加するだけです。たとえば、ユーザーが「アクティブ」とマークされていることを確認できます:
``````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
は必須オプションではなく、単に例として使用されています。データベーステーブル内の「ユーザー名」に対応する列名を使用する必要があります。
``````php
if (Auth::attemptWhen([
'email' => $email,
'password' => $password,
], function (User $user) {
return $user->isNotBanned();
})) {
// Authentication was successful...
}
`
特定のガードインスタンスへのアクセス
`````guard`````メソッドに渡されるガード名は、`````auth.php`````設定ファイルで構成されたガードのいずれかに対応する必要があります:
``````php
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
契約の実装である必要があります。Laravelに含まれるApp\Models\User
モデルは、すでにこのインターフェースを実装しています。この認証方法は、ユーザーがアプリケーションに登録した直後など、すでに有効なユーザーインスタンスを持っている場合に便利です:
use Illuminate\Support\Facades\Auth;
Auth::login($user);
``````php
Auth::login($user, $remember = true);
`
必要に応じて、login
メソッドを呼び出す前に認証ガードを指定できます:
Auth::guard('admin')->login($user);
IDによるユーザーの認証
データベースレコードの主キーを使用してユーザーを認証するには、loginUsingId
メソッドを使用できます。このメソッドは、認証したいユーザーの主キーを受け取ります:
Auth::loginUsingId(1);
``````php
Auth::loginUsingId(1, remember: true);
`
一度の認証
``````php
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
ミドルウェアは、email
データベーステーブルの列がユーザーの「ユーザー名」であると仮定します。
FastCGIに関する注意
PHP FastCGIとApacheを使用してLaravelアプリケーションを提供している場合、HTTP基本認証が正しく機能しないことがあります。これらの問題を修正するには、アプリケーションの.htaccess
ファイルに次の行を追加できます:
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
ステートレスHTTP基本認証
ユーザー識別子クッキーをセッションに設定せずにHTTP基本認証を使用することもできます。これは、HTTP認証を使用してアプリケーションのAPIへのリクエストを認証することを選択した場合に主に役立ちます。これを実現するには、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);
ログアウト
ユーザーをアプリケーションから手動でログアウトさせるには、logout
メソッドをAuth
ファサードで使用できます。これにより、ユーザーのセッションから認証情報が削除され、以降のリクエストは認証されなくなります。
``````php
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 () {
// ...
});
});
次に、logoutOtherDevices
メソッドをAuth
ファサードで使用します。このメソッドは、ユーザーに現在のパスワードを確認することを要求します。アプリケーションは、入力フォームを介してこれを受け入れる必要があります:
use Illuminate\Support\Facades\Auth;
Auth::logoutOtherDevices($currentPassword);
<a name="password-confirmation"></a>
## パスワード確認
アプリケーションを構築しているとき、ユーザーがアクションを実行する前やアプリケーションの機密エリアにリダイレクトされる前に、パスワードを確認する必要があるアクションが時折発生することがあります。Laravelには、このプロセスを簡単にするための組み込みミドルウェアが含まれています。この機能を実装するには、ユーザーにパスワードを確認するように求めるビューを表示するための1つのルートと、パスワードが有効であることを確認し、ユーザーを意図した宛先にリダイレクトするための別のルートを定義する必要があります。
以下のドキュメントでは、Laravelのパスワード確認機能と直接統合する方法について説明します。ただし、より迅速に始めたい場合は、[Laravelアプリケーションスターターキット](/read/laravel-11-x/4f3d9f3a392315aa.md)にこの機能のサポートが含まれています!
<a name="password-confirmation-configuration"></a>
### 設定
パスワードを確認した後、ユーザーは3時間の間、再度パスワードを確認するように求められません。ただし、ユーザーが再度パスワードを求められるまでの時間を変更するには、アプリケーションの`````config/auth.php`````設定ファイル内の`````password_timeout`````設定値を変更する必要があります。
<a name="password-confirmation-routing"></a>
### ルーティング
<a name="the-password-confirmation-form"></a>
#### パスワード確認フォーム
まず、ユーザーにパスワードを確認するように求めるビューを表示するためのルートを定義します:
``````php
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']);
カスタムガードの追加
``````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
{
// ...
/**
* 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
の実装を返す必要があります。このインターフェースには、カスタムガードを定義するために実装する必要があるいくつかのメソッドが含まれています。カスタムガードが定義されたら、guards
設定ファイルのauth.php
設定でガードを参照できます:
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
クロージャリクエストガード
カスタムのHTTPリクエストベースの認証システムを実装する最も簡単な方法は、Auth::viaRequest
メソッドを使用することです。このメソッドを使用すると、単一のクロージャを使用して認証プロセスを迅速に定義できます。
始めるには、アプリケーションのAppServiceProvider
のboot
メソッド内で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();
});
}
カスタム認証ドライバーが定義されたら、guards
設定ファイルのドライバーとして構成できます:
'guards' => [
'api' => [
'driver' => 'custom-token',
],
],
最後に、ルートに認証ミドルウェアを割り当てる際にガードを参照できます:
Route::middleware('auth:api')->group(function () {
// ...
});
カスタムユーザープロバイダーの追加
従来のリレーショナルデータベースを使用してユーザーを保存していない場合は、独自の認証ユーザープロバイダーでLaravelを拡張する必要があります。provider
メソッドをAuth
ファサードで使用して、カスタムユーザープロバイダーを定義します。ユーザープロバイダーリゾルバーは、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'));
});
}
}
``````php
'providers' => [
'users' => [
'driver' => 'mongo',
],
],
`
最後に、このプロバイダーをguards
設定で参照できます:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
ユーザープロバイダー契約
`````Illuminate\Contracts\Auth\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);
}
`
`````retrieveByToken`````関数は、ユーザーのユニーク`````$identifier`````と「記憶する」`````$token`````を取得します。これは通常、`````remember_token`````のようなデータベース列に保存されます。前のメソッドと同様に、`````Authenticatable`````の実装は、このメソッドによって返される必要があります。
`````updateRememberToken`````メソッドは、`````$user`````インスタンスの`````remember_token`````を新しい`````$token`````で更新します。成功した「記憶する」認証試行またはユーザーがログアウトするときに、ユーザーに新しいトークンが割り当てられます。
`````retrieveByCredentials`````メソッドは、アプリケーションに認証を試みる際に`````Auth::attempt`````メソッドに渡される資格情報の配列を受け取ります。このメソッドは、その資格情報に一致するユーザーを永続ストレージに「クエリ」する必要があります。通常、このメソッドは、`````$credentials['username']`````の値に一致する「ユーザー名」を持つユーザーレコードを検索する「where」条件を持つクエリを実行します。メソッドは`````Authenticatable`````の実装を返す必要があります。**このメソッドは、パスワードの検証や認証を試みるべきではありません。**
`````validateCredentials`````メソッドは、与えられた`````$user`````を`````$credentials`````と比較してユーザーを認証します。たとえば、このメソッドは通常、`````Hash::check`````メソッドを使用して`````$user->getAuthPassword()`````の値を`````$credentials['password']`````の値と比較します。このメソッドは、パスワードが有効かどうかを示す`````true`````または`````false`````を返す必要があります。
`````rehashPasswordIfRequired`````メソッドは、必要に応じて与えられた`````$user`````のパスワードを再ハッシュ化します。たとえば、このメソッドは通常、`````Hash::needsRehash`````メソッドを使用して`````$credentials['password']`````の値が再ハッシュ化する必要があるかどうかを判断します。パスワードを再ハッシュ化する必要がある場合、メソッドは`````Hash::make`````メソッドを使用してパスワードを再ハッシュ化し、ユーザーのレコードを永続ストレージ内で更新します。
<a name="the-authenticatable-contract"></a>
### 認証可能契約
`````UserProvider`````の各メソッドを探求したので、`````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
メソッドは、ユーザーのハッシュ化されたパスワードを返す必要があります。
このインターフェースにより、認証システムは、使用しているORMやストレージ抽象化レイヤーに関係なく、任意の「ユーザー」クラスで機能します。デフォルトで、LaravelにはApp\Models\User
クラスがapp/Models
ディレクトリに含まれており、このインターフェースを実装しています。
自動パスワード再ハッシュ
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 |