设置Bearer令牌后Sanctum返回未认证(401)问题求助
问题分析
你遇到的核心问题是:自定义中间件解密Cookie后设置的Authorization头,未被Sanctum的auth:sanctum中间件正确识别。虽然移除auth:sanctum后能确认请求头存在,但Sanctum的认证逻辑可能因请求头读取时机、缓存机制,或是你的设置方式问题,无法捕获到该头信息。
解决方案
以下是几种可行的修复方案,按优先级排序:
方案1:手动在中间件中完成用户认证(推荐)
跳过设置Authorization头的步骤,直接在自定义中间件中通过解密后的token找到用户并绑定到请求对象,让Sanctum直接识别已认证用户:
修改DecryptSanctumTokenMiddleware代码:
use Laravel\Sanctum\PersonalAccessToken; public function handle(Request $request, Closure $next): Response { $encryptedToken = $request->cookie('token'); if (!$encryptedToken) { return $this->failedRequest('', 'Unauthenticated', 401); } try { $decryptedToken = Crypt::decryptString($encryptedToken); } catch (\Illuminate\Contracts\Encryption\DecryptException $e) { return $this->failedRequest('', 'Invalid token', 401); } // 查找对应的Sanctum令牌 $token = PersonalAccessToken::findToken($decryptedToken); if (!$token || $token->expired()) { return $this->failedRequest('', 'Unauthenticated', 401); } // 将用户绑定到请求对象 $request->setUserResolver(function () use ($token) { return $token->tokenable; }); return $next($request); }
修改后,auth:sanctum中间件会直接识别请求中已绑定的用户,无需依赖Authorization头。
方案2:确保Authorization头被Sanctum正确读取
若坚持通过设置Authorization头认证,可同时更新请求的服务器参数(Sanctum的bearerToken()方法会优先从$_SERVER读取):
修改中间件中设置头的代码段:
// 同时设置请求头和服务器参数 $request->headers->set("Authorization", "Bearer $decryptedToken"); $request->server->set('HTTP_AUTHORIZATION', "Bearer $decryptedToken");
Sanctum的TokenGuard获取token时,会优先检查$_SERVER['HTTP_AUTHORIZATION'],直接设置该参数可确保token被正确捕获。
方案3:检查Cookie属性配置
确认登录时设置的Cookie属性符合运行环境要求:
- 若应用在HTTPS环境下,需将Cookie的
secure参数设为true,否则浏览器可能不在HTTPS请求中携带Cookie:
$cookie = Cookie::make('token', $encryptedToken, 60, null, null, env('APP_ENV') === 'production', true);
- 若为跨域请求,需设置
SameSite为'none'并配合secure=true(Laravel 8+支持):
$cookie = Cookie::make('token', $encryptedToken, 60, null, null, env('APP_ENV') === 'production', true, false, 'none');
验证步骤
- 在自定义中间件中添加调试代码,确认解密后的token格式正确(应为Sanctum生成的明文格式,如
xxx|xxx):
dd($decryptedToken);
- 验证
PersonalAccessToken::findToken($decryptedToken)能正确返回令牌模型,且$token->tokenable是对应的用户实例。
内容的提问来源于stack exchange,提问作者henrbu
相关产品推荐
相关产品推荐

