laravel 12.x 中 sanctum 无固有认证漏洞,问题源于配置错误或使用不当;需确保迁移表、引入 hasapitokens、正确配置 guards 和中间件,修复跨域 cookie、避免构造函数中提前读取用户,并严格控制 token 权限与生命周期。

Laravel 12.x 中 Sanctum 本身没有公开的“认证漏洞”,所谓“漏洞”绝大多数是配置错误、使用不当或安全策略缺失导致的认证绕过或失效,比如未认证用户能访问受保护路由、登录后反复提示 401 Unauthenticated、Token 被盗用后长期有效等。真正需要解决的是这些**可被利用的配置与实践缺陷**。
确保基础配置完整且正确
Sanctum 认证链非常依赖初始化步骤,缺一不可:
- 运行
php artisan migrate创建personal_access_tokens表——没有这张表,createToken()静默失败,前端收不到有效 token -
User模型必须引入HasApiTokenstrait,否则createToken方法根本不存在 -
config/auth.php中'guards' => ['sanctum' => [...]]必须存在,且apiguard 的 driver 明确设为'sanctum' -
app/Http/Kernel.php的'api'中间件组顶部,必须有EnsureFrontendRequestsAreStateful::class,且不能混入StartSession或EncryptCookies等 web 中间件
修复跨域与 Cookie 同步问题(生产环境高频原因)
本地正常、上线就 401?大概率是子域名下 Cookie 未正确共享或 CSRF 失效:
-
.env中设置:SESSION_DOMAIN=.your-domain.com(注意开头的.)SANCTUM_STATEFUL_DOMAINS=app.your-domain.com(只写前端完整子域名,不带http://或端口) -
config/session.php中:'secure' => false(HTTP 环境下必须为 false;HTTPS 才设true)'same_site' => 'lax'(推荐,兼顾安全与子域兼容) - 前端调用
/sanctum/csrf-cookie后,必须确认浏览器 DevTools → Application → Cookies 中已存入XSRF-TOKEN和laravel_session,且 Domain 列显示为.your-domain.com
杜绝构造函数中提前读取用户
这是最隐蔽也最常被忽略的问题:中间件在控制器实例化之后才执行。若在 __construct() 中调用 auth()->user(),此时认证尚未发生,返回 null,且该值可能被缓存(尤其单例控制器),导致后续方法始终拿不到用户。
- ❌ 错误写法:
public function __construct() { $this->user = auth()->user(); } - ✅ 正确做法:所有用户相关逻辑移至具体方法内,每次实时获取
public function index(Request $request) { $user = $request->user(); // 或 auth()->user() }
强化 Token 生命周期与权限控制
避免“一次登录,永久有效”的风险:
- 生成 Token 时指定能力(abilities)和过期时间:
$token = $user->createToken('mobile', ['read:posts'], now()->addHour()); - 主动撤销 Token:
$user->currentAccessToken()->delete();或$user->tokens()->delete(); - 禁用无限制通配符能力:避免
['*'],按需声明如['post:create', 'comment:delete'],并在中间件中校验:Route::middleware('auth:sanctum:post:create')->post(...)
不复杂但容易忽略——Sanctum 的安全性不在代码有多“高深”,而在于每一步配置是否严丝合缝、每个请求头是否携带到位、每个 Token 是否最小权限发放。











