Laravel配合axios首次登录返回{two_factor: false}而非Auth::id()如何解决
问题根因
你遇到的现象本质是Laravel Fortify默认适配的是传统服务端渲染(Blade)的表单提交场景,未做前后端分离适配:
- 首次登录请求时,Laravel识别为普通网页请求,账号密码验证通过后直接返回302重定向到首页的响应,你拿到的不是预期的用户数据
- 第二次发起相同登录请求时,你的会话已经是登录状态,请求会被
RedirectIfAuthenticated中间件直接拦截,重定向到首页,才返回了首页控制器的用户ID结果,这不是正常登录流程的返回值
推荐解决方案(适配前后端分离场景,直接返回登录结果)
该方案不需要依赖跳转,登录请求直接返回用户ID,更符合SPA应用的开发逻辑
步骤1:调整axios全局配置
在项目中初始化axios的位置添加以下配置,确保Laravel可以正确识别AJAX请求,同时保留会话状态:
// 标识为AJAX请求 axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; // 携带CSRF令牌,需确保HTML模板中有<meta name="csrf-token" content="{{ csrf_token() }}"> axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').content; // 跨域携带Cookie(如果是同域部署也建议开启) axios.defaults.withCredentials = true;
步骤2:自定义Fortify登录成功响应
打开app/Providers/FortifyServiceProvider.php,在boot方法中添加登录响应的自定义逻辑:
<?php namespace App\Providers; use Laravel\Fortify\Contracts\LoginResponse; use Laravel\Fortify\Fortify; use Illuminate\Support\ServiceProvider; class FortifyServiceProvider extends ServiceProvider { public function boot() { // 自定义登录成功响应 $this->app->instance(LoginResponse::class, new class implements LoginResponse { public function toResponse($request) { if ($request->wantsJson()) { // AJAX请求直接返回用户ID return response()->json([ 'user_id' => auth()->id(), 'code' => 200, 'msg' => '登录成功' ]); } // 普通表单请求走原跳转逻辑 return redirect()->intended(Fortify::redirects('login')); } }); // 原有Fortify配置保留即可 Fortify::ignoreRoutes(); } }
步骤3:调整登录请求逻辑
修改你的Vuex action中的登录代码,直接读取返回的用户ID即可:
actions: { login(context,payload) { axios.post('/login', { email: payload.email, password: payload.password }).then(response => { const userId = response.data.user_id console.log('登录成功,用户ID:', userId) // 这里写登录成功后的后续逻辑,比如存储用户信息到Vuex、跳转页面等 }).catch(error => { if (error.response?.status === 422) { console.log('账号或密码验证失败') } else { console.log('登录异常') } }); }, logout() { axios.post('/logout').then(response => { console.log('退出成功') // 退出成功后的逻辑,比如清空Vuex数据、跳转到登录页等 }).catch(error => { console.log('退出异常') }); }, }
可选解决方案(保留原有跳转逻辑)
如果你不想修改Fortify的默认配置,也可以在登录请求成功后主动调用一次首页接口获取用户ID:
login(context,payload) { axios.post('/login', { email: payload.email, password: payload.password }).then(() => { // 登录请求成功后主动请求首页接口拿用户ID axios.get('/home').then(res => { const userId = res.data console.log('用户ID:', userId) }) }).catch(error => { console.log('登录失败', error) }); }
内容的提问来源于stack exchange,提问作者Ruben Kubalyan
相关产品推荐
相关产品推荐

