Laravel+InertiaJS+VueJS项目登录登出需刷新才可生效问题
问题描述
使用Laravel、inertiajs/inertia-laravel搭配VueJS框架开发项目时遇到异常:完成登录进入仪表盘(dashboard)页面后,点击登出按钮无任何响应,必须手动刷新页面后登出功能才可正常触发;登出完成后再次尝试登录时会出现完全相同的问题,必须再次刷新页面才可正常完成登录操作。
控制台输出日志
[Wed Jul 13 11:17:42 2022] 127.0.0.1:52434 Closing [Wed Jul 13 11:17:43 2022] 127.0.0.1:52437 Accepted [Wed Jul 13 11:17:43 2022] 127.0.0.1:52437 [200]: GET /site.webmanifest [Wed Jul 13 11:17:43 2022] 127.0.0.1:52437 Closing [Wed Jul 13 11:17:43 2022] 127.0.0.1:52438 Accepted [Wed Jul 13 11:17:46 2022] 127.0.0.1:52438 Closed without sending a request; it was probably just an unused speculative preconnection
项目相关代码
路由配置
Route::get('login', 'Auth\LoginController@showLoginForm')->name('login')->middleware('guest'); Route::post('login', 'Auth\LoginController@store')->name('login.attempt')->middleware('guest'); Route::post('logout', 'Auth\LoginController@logout')->name('logout');
登录/登出控制器代码
<?php namespace App\Http\Controllers\Auth; use App\Http\Requests\Auth\LoginRequest; use App\Models\User; use Carbon\Carbon; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Session; use Inertia\Inertia; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use Illuminate\Foundation\Auth\AuthenticatesUsers; class LoginController extends Controller { /* |-------------------------------------------------------------------------- | Login Controller |-------------------------------------------------------------------------- | | This controller handles authenticating users for the application and | redirecting them to their home screen. The controller uses a trait | to conveniently provide its functionality to your applications. | */ use AuthenticatesUsers; /** * Where to redirect users after login. * * @var string */ public $redirectTo = RouteServiceProvider::HOME; /** * Show login form * * @return \Inertia\Response */ public function showLoginForm() { // return Inertia::render('Auth/Login'); return Inertia::render('Auth/Login', [ // ALWAYS included on first visit // OPTIONALLY included on partial reloads // ALWAYS evaluated 'users' => User::get(), // ALWAYS included on first visit // OPTIONALLY included on partial reloads // ONLY evaluated when needed 'users' => fn () => User::get(), // NEVER included on first visit // OPTIONALLY included on partial reloads // ONLY evaluated when needed 'users' => Inertia::lazy(fn () => User::get()), ]); } /** * Handle an incoming authentication request. * * @return \Illuminate\Http\RedirectResponse */ public function store(LoginRequest $request) { $request->authenticate(); $request->session()->regenerate(); return redirect('/'); } /** * Log the user out of the application. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\RedirectResponse */ public function logout(Request $request) { Auth::guard('web')->logout(); $request->session()->invalidate(); return $this->loggedOut($request) ?: redirect('/'); // $request->session()->invalidate(); // $request->session()->regenerateToken(); // return redirect('/'); } }
问题根因与修复方案
该异常是InertiaJS项目POST类请求响应不符合协议规范导致的:登录、登出均为POST请求,控制器中直接返回redirect('/')是Laravel普通重定向响应,不符合Inertia协议要求,前端无法正确处理跳转逻辑,也不会同步更新登录态、CSRF令牌等前端存储状态,最终表现为按钮点击无响应,手动刷新页面后状态同步才恢复正常。另外代码中存在附带错误:showLoginForm方法中三次向Inertia渲染传参定义同名users键,前两次定义会被最后一次覆盖,属于无效代码。
修复操作:
- 所有POST/PUT/DELETE类型的认证相关请求处理完成后,不要返回普通redirect响应,改用Inertia提供的
Inertia::location()方法触发外部重定向,强制前端同步刷新页面状态,也可以给普通redirect加303状态码适配Inertia处理逻辑。 - 修正登出方法逻辑,移除对AuthenticatesUsers trait自带
loggedOut方法的调用,登出销毁会话后手动重新生成CSRF令牌,避免令牌失效拦截后续请求。 - 清理
showLoginForm中重复定义的users传参,根据实际业务需求保留一种传参方式即可。 - 额外检查前端提交逻辑,确认登录、登出按钮的请求是通过Inertia提供的
router.post方法发起,不要使用原生表单默认提交、原生axios直接发请求且不处理Inertia响应头的写法。
修正后的核心方法代码参考:
// 登录提交处理 public function store(LoginRequest $request) { $request->authenticate(); $request->session()->regenerate(); return Inertia::location('/'); } // 登出处理 public function logout(Request $request) { Auth::guard('web')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return Inertia::location('/'); }
内容的提问来源于stack exchange,提问作者seema Goyat
相关产品推荐
相关产品推荐

