调用自有Laravel API返回401未授权问题排查求助
嘿,我来帮你排查这个401未授权的问题——你已经正确配置了CSRF相关的请求头和meta标签,所以问题大概率不是出在CSRF防护上,而是Passport的路由保护逻辑或者API路由的认证中间件配置出了问题。下面是几个你可以逐一排查的方向:
auth:api中间件 这是最常见的原因:如果你的接口是给未登录用户访问的公开接口,却给它加上了auth:api中间件,那必然会返回401。因为auth:api中间件要求请求必须携带有效的Passport令牌,而未登录用户根本没有这个令牌。
打开routes/api.php看看你的路由定义:
// ❌ 错误示例:未登录用户访问会直接返回401 Route::get('/public/info', [PublicController::class, 'getInfo'])->middleware('auth:api'); // ✅ 正确示例:允许未登录用户访问的公开接口,不需要加auth:api Route::get('/public/info', [PublicController::class, 'getInfo']);
如果你是想让登录用户通过会话(而不是手动传递令牌)访问API,那需要确保在web中间件组里添加了Passport的CreateFreshApiToken中间件——这个中间件会自动给登录用户的响应设置laravel_token Cookie,Axios会自动携带这个Cookie完成认证。但注意:这个逻辑只对登录用户有效,未登录用户的公开接口依然不需要加auth:api。
检查app/Http/Kernel.php的web中间件组:
protected $middlewareGroups = [ 'web' => [ // ...其他默认中间件 \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class, ], ];
看看你的全局中间件或者路由中间件列表,有没有自己写的认证/权限校验中间件,错误地给所有请求加上了登录校验。比如有些开发者会不小心把auth中间件加到全局,导致未登录用户的所有请求都被拦截。
虽然你说已经遵循了官方文档,但可以快速核对这几个关键步骤:
- 有没有运行
php artisan passport:install生成加密密钥 User模型是否正确引入了Laravel\Passport\HasApiTokenstraitAuthServiceProvider的boot方法里是否调用了Passport::routes()
总的来说,你的CSRF配置是没问题的,核心问题是要区分公开API和需要登录的API,公开接口绝对不能加auth:api中间件。按照上面的步骤排查,应该能很快解决问题。
内容的提问来源于stack exchange,提问作者panthro

