パスワードの再設定
パスワードを忘れた人のための「パスワードの再設定」を、設定・モデルの準備・ルート・期限切れトークンの削除・メールやリンクの変更まで説明します。
多くのアプリには、パスワードを忘れた人が、自分で新しいパスワードを決められる機能があります。メールで再設定のリンクを送り、そのリンクから新しいパスワードを入れてもらう流れです。Laravel には、再設定のリンクを送る機能と、安全にパスワードを変える機能が最初から入っているので、アプリごとに作り直さなくて済みます。
補足
早く始めたいなら、新しい Laravel アプリにスターターキット(最初から画面や機能がそろった雛形)を入れます。忘れたパスワードの再設定を含む、認証の一式が用意されます。
設定#
パスワードの再設定の設定は、config/auth.php にあります。このファイルのオプションを確かめてください。最初は、database のドライバ(保存の方式)を使う設定になっています。
driver のオプションは、再設定のデータの保存先を決めます。Laravel には、次の2つのドライバがあります。
| ドライバ | 説明 |
|---|---|
database |
再設定のデータを、リレーショナルデータベース(表でデータを持つデータベース)に保存する |
cache |
再設定のデータを、キャッシュ(よく使うものを手元に置いておくしくみ)の保存先のどれかに保存する |
ドライバの準備#
database の場合#
最初の database ドライバを使うなら、再設定のトークン(合言葉のような値)を入れる表が必要です。Laravel の標準の 0001_01_01_000000_create_users_table.php というマイグレーション(表を作る手順書)に、ふつう入っています。
cache の場合#
専用の表が要らない、cache ドライバもあります。データは、ユーザーのメールアドレスの SHA-256 ハッシュ(元に戻せない形に変えた値)をキーにして保存されます。
'passwords' => [
'users' => [
'driver' => 'cache',
'provider' => 'users',
'store' => 'passwords', // 省略できる
'expire' => 60,
'throttle' => 60,
],
],
artisan cache:clear を実行したときに、再設定のデータまで消えないようにしたいなら、store で、別の保存先を指定できます。値は、config/cache.php で設定した保存先の名前にします。
モデルの準備#
パスワードの再設定の機能を使う前に、App\Models\User が、Illuminate\Notifications\Notifiable のトレイト(クラスに機能をまとめて足すしくみ)を使っていることが必要です。新しい Laravel アプリの標準の App\Models\User には、ふつう入っています。
次に、App\Models\User が、Illuminate\Contracts\Auth\CanResetPassword という約束事(決まった形)を実装していることを確かめます。Laravel に入っている App\Models\User は、すでに実装していて、必要なメソッドを足してくれる Illuminate\Auth\Passwords\CanResetPassword のトレイトも使っています。
信頼するホストの設定#
Laravel は、HTTP リクエストの Host ヘッダー(相手が「どのドメイン宛てか」を示す情報)の中身にかかわらず、届いたすべてのリクエストに答えます。さらに、Web のリクエストの処理中に、アプリの絶対 URL(https:// から始まる URL)を作るときに、この Host の値を使います。
ふつうは、Nginx や Apache などの Web サーバーの設定で、決まったホスト名宛てのリクエストだけをアプリへ渡します。Web サーバーの設定を変えられず、Laravel に、決まったホスト名にだけ答えさせたいときは、bootstrap/app.php の trustHosts というミドルウェアのメソッドを使います。パスワードの再設定の機能があるアプリでは、とくに大切です。
このメソッドについては、リクエストのページを見てください。
ルート#
ユーザーにパスワードを再設定させるには、いくつかのルート(URL と処理を結びつけたもの)が必要です。1組目は、メールアドレスを入れて、再設定のリンクを求めるルートです。2組目は、メールで届いたリンクから再設定のフォームを送ったときに、実際にパスワードを変えるルートです。
再設定のリンクを求める#
リンクを求めるフォーム#
まず、再設定のリンクを求めるフォームの画面を返すルートを作ります。
Route::get('/forgot-password', function () {
return view('auth.forgot-password');
})->middleware('guest')->name('password.request');
このルートが返すビュー(画面の見た目を書いたファイル)には、email の入力欄のあるフォームを置きます。そのメールアドレスに、再設定のリンクを求めるためのフォームです。
フォームの送信を処理する#
次に、「パスワードを忘れた」画面のフォームの送信を受けるルートを作ります。メールアドレスを確かめ、そのユーザーに、再設定の案内を送ります。
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
Route::post('/forgot-password', function (Request $request) {
$request->validate(['email' => 'required|email']);
$status = Password::sendResetLink(
$request->only('email')
);
return $status === Password::ResetLinkSent
? back()->with(['status' => __($status)])
: back()->withErrors(['email' => __($status)]);
})->middleware('guest')->name('password.email');
このルートを見ます。まず、リクエストの email を確かめます。次に、Laravel の「パスワードブローカー」(Password ファサードから使う、再設定の仕事を引き受けるしくみ)に、再設定のリンクを送らせます。ブローカーが、指定された項目(ここではメールアドレス)でユーザーを探し、Laravel の通知のしくみで、再設定のリンクを送ります。
sendResetLink は、結果を表す「ステータス」の文字を返します。このステータスは、多言語対応のヘルパーで翻訳でき、ユーザーに分かりやすいメッセージを見せられます。翻訳は、lang/{lang}/passwords.php という言語ファイルで決まります。ステータスのとりうる値ごとに、このファイルに1行あります。
補足
Laravel の最初のアプリには、lang フォルダが入っていません。Laravel の言語ファイルを変えたいときは、lang:publish という Artisan コマンド(php artisan で動かす Laravel のコマンド)で公開できます。
sendResetLink を呼んだときに、Laravel が、どうやってユーザーをデータベースから探すのか、不思議に思うかもしれません。パスワードブローカーは、認証の「ユーザープロバイダ」(ユーザーの取り出し方を決めるしくみ)を使って探します。ブローカーが使うプロバイダは、config/auth.php の passwords の設定で決まります。自分のユーザープロバイダを作る方法は、認証のページを見てください。
補足
パスワードの再設定を自分で作るときは、画面とルートの中身を、自分で作る必要があります。必要な認証の処理が全部そろった雛形がほしいなら、スターターキットを見てください。
パスワードを再設定する#
再設定のフォーム#
次に、ユーザーがメールの再設定のリンクを押して、新しいパスワードを入れたときに、実際にパスワードを変えるルートを作ります。まず、リンクを押したときに出す、再設定のフォームを出すルートです。このルートは、あとで再設定のリクエストを確かめるための token のパラメータを受け取ります。
Route::get('/reset-password/{token}', function (string $token) {
return view('auth.reset-password', ['token' => $token]);
})->middleware('guest')->name('password.reset');
このルートが返すビューには、次の入力欄のあるフォームを置きます。
email(メールアドレス)password(新しいパスワード)password_confirmation(新しいパスワードの確認)- 隠した
token(ルートが受け取った、秘密の$tokenの値を入れる)
フォームの送信を処理する#
次に、再設定のフォームの送信を処理するルートを作ります。届いた内容を確かめ、データベースのユーザーのパスワードを更新します。
use App\Models\User;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
Route::post('/reset-password', function (Request $request) {
$request->validate([
'token' => 'required',
'email' => 'required|email',
'password' => 'required|min:8|confirmed',
]);
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function (User $user, string $password) {
$user->forceFill([
'password' => Hash::make($password)
])->setRememberToken(Str::random(60));
$user->save();
event(new PasswordReset($user));
}
);
return $status === Password::PasswordReset
? redirect()->route('login')->with('status', __($status))
: back()->withErrors(['email' => [__($status)]]);
})->middleware('guest')->name('password.update');
このルートを見ます。まず、リクエストの token・email・password を確かめます。次に、パスワードブローカーを使って、再設定のリクエストの情報が正しいかを確かめます。
ブローカーに渡した、トークン・メールアドレス・パスワードが正しければ、reset に渡したクロージャ(名前のない関数)が呼ばれます。クロージャは、ユーザーと、再設定のフォームに入れられた、そのままの文字のパスワードを受け取ります。ここで、データベースのユーザーのパスワードを更新します。
reset も、結果のステータスの文字を返します。このステータスは、多言語対応のヘルパーで翻訳できます。翻訳は、lang/{lang}/passwords.php で決まります。アプリに lang フォルダがなければ、lang:publish で作れます。
ここでも、reset を呼んだときに、Laravel がユーザーを探す方法は、認証の「ユーザープロバイダ」です。ブローカーが使うプロバイダは、config/auth.php の passwords で決まります。
期限切れのトークンを消す#
database ドライバを使っていると、期限が切れた再設定のトークンも、データベースに残ります。auth:clear-resets という Artisan コマンドで、かんたんに消せます。
php artisan auth:clear-resets
自動で消したいなら、アプリのスケジューラ(決まった時刻に仕事を動かすしくみ)にこのコマンドを足します。
use Illuminate\Support\Facades\Schedule;
Schedule::command('auth:clear-resets')->everyFifteenMinutes();
変更する#
再設定のリンクを変える#
再設定のリンクの URL は、ResetPassword という通知のクラスの createUrlUsing で変えられます。ユーザーと、再設定のリンクのトークンを受け取るクロージャを渡します。ふつう、アプリの AppServiceProvider の boot の中で呼びます。
use App\Models\User;
use Illuminate\Auth\Notifications\ResetPassword;
/**
* アプリのサービスを起動する
*/
public function boot(): void
{
ResetPassword::createUrlUsing(function (User $user, string $token) {
return 'https://example.com/reset-password?token='.$token;
});
}
再設定のメールを変える#
再設定のリンクを送る通知のクラスは、簡単に変えられます。App\Models\User の sendPasswordResetNotification を上書きします(自分のクラスで書き直します)。このメソッドの中で、自分で作った通知のクラスを使って、通知を送れます。メソッドの第1引数が、再設定の $token です。このトークンを使って、好きな再設定の URL を作り、ユーザーに通知を送れます。
use App\Notifications\ResetPasswordNotification;
/**
* ユーザーに、パスワードの再設定の通知を送る
*
* @param string $token
*/
public function sendPasswordResetNotification($token): void
{
$url = 'https://example.com/reset-password?token='.$token;
$this->notify(new ResetPasswordNotification($url));
}
関連するページ#
公式ドキュメント(英語)
2026年10月5日時点の内容をもとに、日本語でまとめています。