Laravel 9中通过邮件链接完成邮箱变更后登出用户并跳转至登录页的实现方法
实现点击密码重置链接时自动登出当前用户并重定向到登录页
我来帮你搞定这个需求,在Laravel 9里实现这个功能其实很简单,分两种常见的认证场景来给你一步步说明,你可以根据自己用的是默认Auth脚手架还是Breeze来选择对应的方案:
场景一:用的是Laravel默认的Auth脚手架(非Breeze/Fortify)
1. 修改密码重置表单的控制器方法
首先找到App\Http\Controllers\Auth\PasswordResetController.php,修改里面的showResetForm方法——这个方法就是负责显示密码重置表单的,我们要在这里加入登出逻辑:
use Illuminate\Support\Facades\Auth; public function showResetForm(Request $request, $token = null) { // 先检查有没有用户已经登录,有的话直接登出 if (Auth::check()) { Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); } // 跳转到登录页,顺便把重置需要的token和email存在session里,方便登录后直接回到重置流程 return redirect()->route('login')->with([ 'reset_token' => $token, 'reset_email' => $request->email ]); }
2. 让用户登录后自动回到重置页面
接下来打开App\Http\Controllers\Auth\LoginController.php,添加或者修改authenticated方法,处理登录后的跳转逻辑:
protected function authenticated(Request $request, $user) { // 看看session里有没有之前存的重置参数,有的话直接跳回重置页面 if ($request->session()->has('reset_token') && $request->session()->has('reset_email')) { $token = $request->session()->pull('reset_token'); $email = $request->session()->pull('reset_email'); return redirect()->route('password.reset', ['token' => $token, 'email' => $email]); } // 没有重置参数的话,就走默认的登录后跳转逻辑 return redirect()->intended($this->redirectPath()); }
场景二:用的是Laravel Breeze(9.x版本常用的轻量认证脚手架)
1. 自定义一个强制登出的中间件
先生成一个新的中间件:
php artisan make:middleware LogoutAuthenticatedUser
打开生成的App\Http\Middleware\LogoutAuthenticatedUser.php,修改handle方法:
use Closure; use Illuminate\Support\Facades\Auth; public function handle(Request $request, Closure $next) { if (Auth::check()) { Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); // 同样携带重置参数跳转到登录页 return redirect()->route('login')->with([ 'reset_token' => $request->route('token'), 'reset_email' => $request->email ]); } return $next($request); }
2. 注册这个中间件
打开App\Http\Kernel.php,在$routeMiddleware数组里添加我们刚做的中间件:
protected $routeMiddleware = [ // ...其他已有的中间件 'logout.authenticated' => \App\Http\Middleware\LogoutAuthenticatedUser::class, ];
3. 给密码重置路由加上这个中间件
打开routes/auth.php,找到显示重置表单的路由,给它加上我们的中间件:
Route::get('/reset-password/{token}', [NewPasswordController::class, 'create']) ->name('password.reset') ->middleware('logout.authenticated');
4. 修改登录后的跳转逻辑
打开App\Http\Controllers\Auth\AuthenticatedSessionController.php,在登录成功的代码块(也就是Auth::login($user)之后)加入这段逻辑:
// 检查session里的重置参数,有的话直接跳回重置页面 if (session()->has('reset_token') && session()->has('reset_email')) { $token = session()->pull('reset_token'); $email = session()->pull('reset_email'); return redirect()->route('password.reset', ['token' => $token, 'email' => $email]); }
额外小提示
- 如果你只需要登出后直接跳转到登录页,不需要后续自动回到重置流程,那可以去掉携带参数的部分,直接写
return redirect()->route('login');就行。 - 登出时执行
$request->session()->invalidate()和$request->session()->regenerateToken()是Laravel官方推荐的安全操作,能避免会话固定攻击,最好不要省略。
内容的提问来源于stack exchange,提问作者Gandalf
相关产品推荐
相关产品推荐

