必须同步升级 sanctum 至 4.0,否则 api 认证完全失效:中间件不触发、@authenticated 消失、tokencant 报错、personal_access_tokens 表写入失败;需确保 php ≥8.2、laravel 11.x,并更新 composer.json、发布迁移、重构中间件与 user 模型、验证认证链。

升级 Laravel 11 时必须同步适配 Sanctum 4.0,否则 API 认证将完全失效——中间件不触发、@authenticated 标签消失、tokenCant 方法报错、personal_access_tokens 表写入失败,所有依赖 Sanctum 的登录、权限校验、令牌生成逻辑都会中断。
确认 Sanctum 版本与 PHP 环境匹配
先运行 php -v 检查 PHP 版本,必须 ≥ 8.2,Sanctum 4.0 不兼容 PHP 8.1 及更低版本;低于则升级 PHP 后再继续。
执行 composer show laravel/sanctum 查看当前 Sanctum 版本,若显示 3.x 或 2.x,说明尚未升级,需立即处理。
运行 php artisan --version 和 composer show laravel/framework 双重验证 Laravel 是否已升至 11.x,避免出现 Sanctum 4.0 + Laravel 10.x 这种不兼容组合。
更新 composer.json 并强制拉取新版依赖
打开 composer.json,在 require 区块中确保包含:"laravel/sanctum": "^4.0" 和 "php": "^8.2"。
删除 config/sanctum.php 中已废弃的 'middleware' => ['auth'] 字符串式配置项,Sanctum 4.0 要求全部使用完整类名引用。
执行 composer update laravel/sanctum --with-all-dependencies,不能只更新 sanctum 单个包,否则 collision、ignition 等配套工具版本不匹配会导致 artisan 命令启动失败。
发布迁移并重置中间件注册路径
第一步:运行 php artisan vendor:publish --tag=sanctum-migrations,Sanctum 4.0 不再自动加载迁移,这一步漏掉会导致 personal_access_tokens 表缺失,createToken 直接抛出 SQL 错误。
第二步:执行 php artisan migrate,确认表已创建且字段完整(尤其检查 expires_at 是否存在,这是 4.0 新增字段)。
第三步:打开 bootstrap/app.php,在 $app->withRouting() 之后添加:$app->configure('sanctum');,Laravel 11 强制要求 Sanctum 配置在路由加载后激活,否则 RequestContextStrategy 不生效,@middleware 注释被跳过。
第四步:删除 app/Http/Kernel.php 中的 $middlewareGroups 和 $middleware 属性(即使留空也要删),Laravel 11 已彻底移除 Kernel 的中间件反射逻辑,残留会导致文档生成器读取为空。
重构 User 模型与认证控制器
方法一:检查 App\Models\User 是否已引入 HasApiTokens trait,若仍用旧版 use Laravel\Sanctum\HasApiTokens; 则无需改动;但若项目曾手动重写 createToken,必须按新签名调整:public function createToken(string $name, array $abilities = ['*'], ?DateTimeInterface $expiresAt = null),第三个参数不可省略,默认为 null,否则调用时会报 ArgumentCountError。
方法二:登录接口中,原 $user->createToken('api-token')->plainTextToken 仍可用,但若需设置过期时间,必须传入 expiresAt 参数:$user->createToken('mobile', ['read'], now()->addWeeks(2))。
方法三:权限校验改用新辅助方法 tokenCant,例如:if ($user->tokenCant('delete-posts')) { abort(403); },该方法仅在 Sanctum 4.0.7+ 可用,低于此版本需回退至 !$user->tokenCan('delete-posts')。
验证认证链是否完整生效
① 运行 php artisan apidoc:generate --dry-run,检查输出中是否列出 auth:sanctum 和 throttle:api 中间件链,未出现即说明中间件注册失败。
② 在 routes/api.php 中临时添加测试路由:Route::middleware('auth:sanctum')->get('/test-auth', fn() => 'ok');,用 Postman 发送带 Authorization: Bearer xxx 的请求,返回 200 才算通过。
③ 执行 php artisan tinker,输入:
Auth::attempt(['email' => 'test@example.com', 'password' => 'secret']);<br>auth()->user()->createToken('cli')->plainTextToken;,能成功返回 token 字符串才表示模型层正常。
④ 检查日志 storage/logs/laravel.log,搜索关键词 Sanctum 和 RequestContextStrategy,若出现 Strategy not registered 提示,说明 bootstrap/app.php 中配置时机错误。











