From ba3cc6fe91986b54ec60b957109bf58ec2e00438 Mon Sep 17 00:00:00 2001 From: hans362 Date: Mon, 26 Jan 2026 10:07:38 +0800 Subject: [PATCH] fix: generate temporary email verification link with email hash included --- app/Http/Controllers/AuthController.php | 6 +++--- app/Http/Controllers/UserController.php | 2 +- app/Listeners/SendEmailVerification.php | 2 +- routes/web.php | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index 3b10ce2c..1f224cf8 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -344,20 +344,20 @@ class AuthController extends Controller return redirect('/user'); } - public function verify(Request $request) + public function verify(Request $request, User $user) { if (!option('require_verification')) { throw new PrettyPageException(trans('user.verification.disabled'), 1); } - abort_unless($request->hasValidSignature(false), 403, trans('auth.verify.invalid')); + abort_unless($request->hasValidSignature(false) && hash_equals((string)$request->route('hash'), sha1($user->email)), 403, trans('auth.verify.invalid')); return view('auth.verify'); } public function handleVerify(Request $request, User $user) { - abort_unless($request->hasValidSignature(false), 403, trans('auth.verify.invalid')); + abort_unless($request->hasValidSignature(false) && hash_equals((string)$request->route('hash'), sha1($user->email)), 403, trans('auth.verify.invalid')); ['email' => $email] = $request->validate(['email' => 'required|email']); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index c464f992..b5c63b15 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -157,7 +157,7 @@ class UserController extends Controller return json(trans('user.verification.verified'), 1); } - $url = URL::signedRoute('auth.verify', ['user' => $user], null, false); + $url = URL::temporarySignedRoute('auth.verify', Carbon::now()->addHour(), ['user' => $user, 'hash' => sha1($user->email)], false); try { Mail::to($user->email)->send(new EmailVerification(url($url))); diff --git a/app/Listeners/SendEmailVerification.php b/app/Listeners/SendEmailVerification.php index 097fd169..35ebadfb 100644 --- a/app/Listeners/SendEmailVerification.php +++ b/app/Listeners/SendEmailVerification.php @@ -12,7 +12,7 @@ class SendEmailVerification public function handle(User $user) { if (option('require_verification')) { - $url = URL::signedRoute('auth.verify', ['user' => $user->uid], null, false); + $url = URL::temporarySignedRoute('auth.verify', Carbon::now()->addHour(), ['user' => $user, 'hash' => sha1($user->email)], false); try { Mail::to($user->email)->send(new EmailVerification(url($url))); diff --git a/routes/web.php b/routes/web.php index 06cb4ba9..0f5cdf94 100644 --- a/routes/web.php +++ b/routes/web.php @@ -41,8 +41,8 @@ Route::prefix('auth')->name('auth.')->group(function () { Route::post('bind', 'AuthController@fillEmail')->name('verify'); }); - Route::get('verify/{user}', 'AuthController@verify')->name('verify'); - Route::post('verify/{user}', 'AuthController@handleVerify')->name('handle.verify'); + Route::get('verify/{user}/{hash}', 'AuthController@verify')->name('verify'); + Route::post('verify/{user}/{hash}', 'AuthController@handleVerify')->name('handle.verify'); }); Route::prefix('user')