
Laravel Sanctum 中 auth:sanctum 中间件不生效,常因请求未正确携带认证头、跨域配置缺失或控制器构造函数中过早访问认证用户导致;本文详解排查步骤、修复方案及最佳实践。
laravel sanctum 中 `auth:sanctum` 中间件不生效,常因请求未正确携带认证头、跨域配置缺失或控制器构造函数中过早访问认证用户导致;本文详解排查步骤、修复方案及最佳实践。
在使用 Laravel Sanctum 构建 API 应用时,即使成功生成了有效 Token(如通过 /login 接口),仍可能遇到 auth:sanctum 中间件“形同虚设”——受保护路由对未认证用户完全开放。你已确认 auth('sanctum')->check() 在控制器方法内能正确返回 true/false,这说明 Sanctum 的核心鉴权逻辑是可用的;问题往往出在中间件执行时机或请求上下文完整性上。
? 常见根本原因分析
跨域请求未携带凭证头(CORS 问题)
前端(如 Vue/React)调用 API 时若未设置credentials: 'include'(fetch)或withCredentials: true(Axios),浏览器不会发送Cookie,而 Sanctum 默认依赖 Cookie 进行会话认证(尤其在 SPA 场景)。此时auth:sanctum中间件无法读取 session,直接跳过认证。CSRF 令牌缺失(仅限 Cookie 认证)
Sanctum 要求非 GET 请求(如 POST/PUT/DELETE)必须附带有效的 CSRF token(通过X-XSRF-TOKEN头传递)。若前端未从/sanctum/csrf-cookie预请求获取并设置该 header,请求将被拒绝或绕过认证。控制器构造函数中提前调用
auth()->user()
这正是你案例中的关键问题:Laravel 的中间件在控制器实例化之后才执行。若在__construct()中直接调用auth()->user(),此时auth:sanctum尚未运行,auth()返回空用户(null),且该状态会被缓存(尤其在单例控制器中),导致后续方法中auth()->user()始终为null,即使中间件已成功认证。
✅ 正确修复方案
方案一:避免在构造函数中访问认证用户(推荐)
删除构造函数中所有 auth()->user() 调用,改在具体方法中按需获取:
// ❌ 错误:构造函数中访问 auth()
public function __construct()
{
$this->user = auth()->user(); // 此时中间件未执行,$this->user 恒为 null
}
// ✅ 正确:方法内实时获取
public function getBalance(Request $request, string $service, string $account)
{
$user = auth()->user(); // 此时 auth:sanctum 已执行,$user 有效
// ... 业务逻辑
}方案二:使用闭包中间件延迟绑定(如需在构造函数中初始化)
若确实需要在控制器生命周期早期访问用户(例如初始化服务类),应使用闭包中间件确保其在认证后执行:
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->user = auth()->user(); // ✅ 此处 auth() 已被 sanctum 中间件填充
return $next($request);
});
}⚠️ 注意:此方式要求该控制器必须被
auth:sanctum中间件包裹(即定义在Route::group(['middleware' => ['auth:sanctum']])内),否则闭包中的auth()->user()依然为空。
? 其他必要检查项
-
确认
config/sanctum.php中stateful配置匹配前端域名:'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:3000,127.0.0.1')), -
确保
app/Http/Kernel.php中api中间件组包含EnsureFrontendRequestsAreStateful::class(用于 Cookie 认证)。 -
验证请求 Header:使用 Postman/curl 测试时,手动添加
Authorization: Bearer {token}可绕过 Cookie/CSRF 限制,快速验证 Token 认证是否正常:curl -X GET http://your-app.test/api/services/xxx/accounts/123/balance \ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..."
✅ 总结
auth:sanctum 失效绝非 Sanctum 本身缺陷,而是典型的应用集成问题。核心原则是:认证中间件必须在任何依赖认证状态的代码执行前完成。优先采用“按需获取用户”的方式,避免构造函数陷阱;同时严格校验跨域、CSRF 和配置一致性。完成上述调整后,你的路由组将真正实现细粒度权限控制。



















