LaravelのFortifyのForgot passwordの機能において、デフォルトではパスワードリセットしたいアカウントを入力したときに存在するアカウントだと「メールを送信しました」というようなメッセージが表示され、アカウントが存在しない場合はその旨を知らせるメッセージが表示されます。
これだとそのシステムにアカウントがあるかどうかが分かってしまうのでセキュリティ的にはあまり良くありません。
なのでいずれの場合も「メールを送信しました」というメッセージを表示させるということをしたい時があると思います。
少し調べたのですがあまり情報がなかったのでここに記載しておきます。
実装方法
まずroutes/web.phpにコードを追加します。
forgot-passwordが呼び出されたときに自前のPasswordResetLinkControllerを呼び出すようにしています。
use App\Http\Controllers\Auth\PasswordResetLinkController;
Route::get('/forgot-password', [PasswordResetLinkController::class, 'create'])
->middleware(['guest'])
->name('password.request');
Route::post('/forgot-password', [PasswordResetLinkController::class, 'store'])
->middleware(['guest'])
->name('password.email');
次にapp\Http\Controllers\AuthにPasswordResetLinkController.phpを作成し中身を以下のようにします。
元の動作としては
if ($status === Password::RESET_LINK_SENT)
のような条件文を入れて正常なときとアカウントがなかった時でメッセージを表示分けするわけですが今回は同じメッセージで良いのでどんな場合でも同じメッセージを返すようにしています。
メッセージは「パスワードリセットリンクのメールを送信しました。届かない場合はメールアドレスが間違っていないか、迷惑メールフォルダに入っていないかを確認してください」的な感じにするとさらに親切かと思います。
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use Illuminate\Contracts\Support\Responsable;
use Laravel\Fortify\Http\Controllers\PasswordResetLinkController as FortifyPasswordResetLinkController;
use Illuminate\Support\Facades\Password;
use Laravel\Fortify\Contracts\SuccessfulPasswordResetLinkRequestResponse;
class PasswordResetLinkController extends FortifyPasswordResetLinkController
{
public function store(Request $request): Responsable
{
$request->validate(['email' => 'required|email']);
$status = Password::sendResetLink(
$request->only('email')
);
return app(SuccessfulPasswordResetLinkRequestResponse::class, ['status' => "メールを送信しました"]);
}
}
以上で完了です。
アカウントが存在しない場合でも同じメッセージが表示されるか確認してみてください。