Laravel微服务Sanctum认证遇401未授权问题(已解决)
Laravel跨项目Sanctum认证中间件未授权排查方案
问题背景
有两个Laravel项目,其中一个集成Laravel Sanctum作为认证服务端,另一个通过自定义中间件调用该服务端的/v1/management/auth/me接口完成认证。执行中间件时返回未授权,但用Postman直接调用该接口正常;仅当认证服务端用php artisan serve启动,且中间件的$url设为127.0.0.1:8000或localhost:8000时,认证流程能正常运行。
中间件代码(调用方项目)
$url = 'http://localhost/v1/management/auth/me'; $suepackAuth = Http::withToken( ltrim($request->header('Authorization'),'Bearer ') )->withHeaders(['Accept' => 'application/json', 'secret' => '65dsa156sda15dsa1dsa65'])->get($url); echo ($suepackAuth->body()); if (!$suepackAuth->ok()) throw new AuthenticationException(); // auth()->login(); return $next($request);
认证服务端项目Kernel配置
/** * The application's global HTTP middleware stack. * * These middleware are run during every request to your application. * * @var array<int, class-string|string> */ protected $middleware = [ // \App\Http\Middleware\TrustHosts::class, \App\Http\Middleware\TrustProxies::class, \Illuminate\Http\Middleware\HandleCors::class, // \App\Http\Middleware\PreventRequestsDuringMaintenance::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ]; /** * The application's route middleware groups. * * @var array<string, array<int, class-string|string>> */ protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ];
排查与解决步骤
检查本地服务器端口路由
使用http://localhost不带端口时,本地Web服务器(Nginx/Apache)可能将请求转发到了错误的项目端口:- 确认认证服务端的运行端口,检查Web服务器配置是否将
localhost请求路由到该端口 - 若两个项目使用不同端口,需在
$url中明确指定认证服务端的端口(如http://localhost:8001/v1/management/auth/me)
- 确认认证服务端的运行端口,检查Web服务器配置是否将
配置Sanctum状态化信任域名
若跨项目认证需要保持会话状态,在认证服务端的config/sanctum.php中添加调用方项目的域名到stateful数组:'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1,调用方项目域名')),同时设置
SESSION_DOMAIN环境变量为.localhost(允许同域下的子项目共享会话)。验证请求Token与头信息
- 检查
Authorization头处理逻辑:ltrim($request->header('Authorization'),'Bearer ')是否正确移除前缀,避免Token包含多余空格 - 若认证服务端的
auth/me接口不需要secret头,移除该参数,避免干扰Sanctum的认证流程
- 检查
调试请求响应细节
在调用方中间件中添加调试代码,查看具体错误信息:// 打印原始Token和处理后的Token dd($request->header('Authorization'), ltrim($request->header('Authorization'),'Bearer ')); // 打印Sanctum返回的状态码和响应内容 dd($suepackAuth->status(), $suepackAuth->json());根据返回的错误(如Token无效、CSRF缺失)定位具体问题。
确认Sanctum路由中间件
检查认证服务端的auth/me路由是否正确使用auth:sanctum中间件:Route::middleware('auth:sanctum')->get('/v1/management/auth/me', function (Request $request) { return $request->user(); });
内容的提问来源于stack exchange,提问作者milad modaresi
相关产品推荐
相关产品推荐

