Nuxt.js集成Laravel Sanctum时Staging环境$auth.user为空问题
Nuxt.js搭配Laravel Sanctum认证预发布环境异常问题
问题描述
使用Nuxt.js搭配Laravel Sanctum实现认证功能时,本地环境运行正常,Staging预发布环境出现登录后无法获取用户信息的异常。
现有登录实现代码
const response = await axios.get(`${process.env.apiUrl}/sanctum/csrf-cookie`) console.log(response) const res = await this.$auth.loginWith('laravelSanctum', { data: { email: this.userLogin.login.email, password: this.userLogin.login.password, } }) console.log(res); console.log(this.$auth) this.$router.push('/mon-compte/mon-espace');
环境表现差异
本地环境正常表现
- /sanctum/csrf-cookie接口请求成功,CSRF Cookie正常获取
- 登录接口请求成功
- $auth.user包含接口返回的全部用户信息
- 整个登录流程共发起3个接口请求:csrf-cookie、login、user,可正常完成登录跳转
Staging预发布环境异常表现
- /sanctum/csrf-cookie接口请求正常
- 登录接口请求正常
- $auth.user为空,登录流程仅发起csrf-cookie、login 2个接口请求,未触发user接口请求,无法正常获取登录用户信息
现有配置与业务代码
1. nuxt.config.js auth模块配置
auth: { strategies: { 'laravelSanctum': { provider: 'laravel/sanctum', url: process.env.apiUrl, endpoints:{ login: { url: '/api/login', method: 'post', propertyName: 'access_token' }, user: { url: '/api/user', method: 'get', propertyName: false }, logout: { url: '/api/logout', method: 'post' }, }, register: { url: '/api/register', method: 'post' } } }, redirect: { login: '/mon-compte/login', logout: '/mon-compte/login', home: '/mon-compte/mon-espace', register: '/mon-compte/register' } },
2. Laravel侧api.php路由定义
Route::apiResource('user', UserController::class); Route::post('/login', [AuthController::class, 'login']); Route::post('/logout', [AuthController::class, 'logout']); Route::post('/register', [AuthController::class, 'register']); Route::post('/me', [AuthController::class, 'me']);
3. AuthController相关业务代码
public function register(Request $request) { $validateData = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:8' ]); $user = User::create([ 'email' => $validateData['email'], 'name' => $validateData['name'], 'type' => 'user', 'password' => bcrypt($validateData['password']) ]); $token = $user->createToken('auth_token')->plainTextToken; return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer' ]); } public function login(Request $request) { if (!Auth::attempt($request->only('email', 'password'))) { return response()->json([ 'message' => 'Login information is invalid.' ], 401); } $user = User::where('email', $request['email'])->firstOrFail(); $token = $user->createToken('authToken')->plainTextToken; return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', 'user' => $user ]); } public function me(Request $request) { return response()->json(['data' => $request->user(), "result" => true]); } public function logout(Request $request){ Auth::logout(); auth()->guard('sanctum')->logout(); //auth('sanctum')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return response()->json(['message' => 'Client successfully signed out']); }
问题根因与修复方案
问题由配置不匹配、认证模式混用、预发布环境跨域cookie配置错误共同导致,本地环境宽松配置掩盖了潜在问题,具体修复点如下:
- 修复user接口配置不匹配问题
当前Nuxt配置中user接口地址为/api/user,但apiResource注册的该路由是获取指定ID用户的资源路由,并非获取当前登录用户的接口;实际获取当前登录用户的接口是自定义的/api/me。本地未触发报错是因为登录接口直接返回了user字段,auth模块本地直接读取了登录响应内的用户信息,预发布环境认证逻辑未走通时就无法获取用户。
修改nuxt.config.js中user端点配置:user: { url: '/api/me', method: 'get', propertyName: 'data' // 对应/me接口返回的用户数据所在的data字段 } - 修复Sanctum认证模式混用问题
laravel/sanctumprovider默认适配SPA Cookie认证模式,依赖CSRF Cookie、Session会话完成认证,不需要手动生成access_token;但当前代码中登录/注册逻辑手动调用createToken生成令牌返回,同时配置了propertyName: 'access_token',相当于告知auth模块走Token认证模式,该模式下auth模块拿到令牌后不会主动发起user信息请求。本地能正常请求user接口是因为本地Cookie携带正常,auth模块自动走了Cookie认证逻辑,预发布环境Cookie跨域失效后就只走Token逻辑,不会请求user接口。
修复方式:如果Nuxt前端与Laravel API属于同主域名的SPA应用,直接删除登录、注册方法中生成access_token的逻辑,登录成功后正常返回响应即可,认证状态全靠Cookie传递;如果是跨域分离部署需要走Token认证,替换laravel/sanctumprovider为默认local scheme,手动配置Token存储与请求头携带逻辑。 - 修复预发布环境跨域与Cookie配置
预发布环境认证Cookie无法正常携带是未触发user请求的核心诱因,逐项检查以下配置:- Laravel侧
config/cors.php中supports_credentials设为true,allowed_origins加入预发布前端完整域名 - Laravel侧
config/sanctum.php中stateful数组加入预发布前端域名 - Laravel侧
config/session.php中domain设置为服务主域名(例:前端为staging.demo.com、API为api.demo.com时,设为.demo.com),HTTPS环境下secure设为true,same_site设为lax,纯跨域场景下设为none - Nuxt侧axios全局配置开启
withCredentials: true,保证跨域请求自动携带Cookie
- Laravel侧
- 可选补充配置:在laravelSanctum策略配置中加入
autoFetchUser: true,强制登录成功后发起用户信息请求,前提是user接口地址配置正确。
内容的提问来源于stack exchange,提问作者Vin Parker
相关产品推荐
相关产品推荐

