Laravel中Sanctum API认证与Web后台认证共存问题
Laravel Sanctum 与Web后台认证共存解决方案
问题根源
配置Sanctum状态式SPA认证后,若默认认证守卫被设置为sanctum,或代码中未明确指定Web认证使用web守卫,会导致后台Web会话无法被正确识别,出现登录后中间件中auth()->user()返回null的情况。
具体修复步骤
1. 确认认证守卫配置
打开config/auth.php,确保默认守卫仍为web,同时sanctum守卫配置正确:
return [ 'defaults' => [ 'guard' => 'web', // 保持默认守卫为web 'passwords' => 'users', ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'sanctum' => [ 'driver' => 'sanctum', 'provider' => 'users', 'hash' => false, ], ], // ... 其他配置 ];
2. 修改后台登录代码,明确使用web守卫
将登录逻辑中的认证操作指定为web守卫,确保Web会话被正确创建:
// 替换原attempt和login代码 if (!Auth::guard('web')->attempt(['email' => $this->email, 'password' => $this->password, 'role' => 'admin'])) { $this->dispatchBrowserEvent('error', ['message' => 'Invalid Credentials, Check your credentials']); return; } $user = User::whereEmail($this->email)->first(); $auth_user = Auth::guard('web')->login($user, $this->remember); dd(auth()->guard('web')->user()); // 现在可以正确获取web守卫下的用户 $this->dispatchBrowserEvent('success', ['message' => 'Login Successfully']); return redirect()->route('admin.dashboard');
3. 修复自定义后台认证中间件
在中间件中同样明确使用web守卫来校验用户:
// 替换原中间件代码 $guard = Auth::guard('web'); dd($guard->user()); // 现在能正确获取登录用户 if (!$guard->check()) { return redirect()->route('admin.login'); } if ($guard->user()->role != 'admin') { return redirect()->route('admin.login'); } return $next($request);
4. 路由中间件分组区分
确保后台Web路由使用web中间件组,API路由使用api中间件组(含auth:sanctum):
- 后台路由示例:
Route::prefix('admin') ->middleware(['web', 'admin.auth']) // 使用web中间件组+自定义admin中间件 ->group(function () { Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard'); // 其他后台路由 }); // 登录路由不需要admin.auth中间件 Route::get('/admin/login', [AdminLoginController::class, 'show'])->name('admin.login'); Route::post('/admin/login', [AdminLoginController::class, 'store']);
- API路由示例:
Route::prefix('api') ->middleware(['api', 'auth:sanctum']) ->group(function () { // API接口路由 });
核心原理
Laravel的认证系统支持多守卫,web守卫基于Session实现传统Web认证,sanctum守卫支持Token/SPA状态式认证。明确指定守卫后,两者的会话/认证状态互不干扰,即可实现共存。
内容的提问来源于stack exchange,提问作者Patrick Obafemi
相关产品推荐
相关产品推荐

