Laravel Sanctum调用currentAccessToken()->delete测试报错但生产环境正常
错误原因
这个报错是因为测试环境下,调用currentAccessToken()返回的是Laravel\Sanctum\TransientToken类实例,该类是Sanctum专为通过Session(web guard)登录的用户生成的临时令牌对象,本身没有实现delete()方法。只有真实存储在personal_access_tokens表中的持久化令牌实例,才支持调用delete()方法删除。
正式环境不会触发该问题,是因为正式环境的API请求都通过Bearer令牌完成认证,不会走Session登录逻辑,拿到的都是持久化令牌实例。
解决方案
方案1:修改控制器兼容场景
在控制器中判断当前令牌类型,对临时令牌跳过删除操作即可,不会影响正式环境的正常逻辑:
// * 删除当前访问令牌 public function signOut(Request $request) { $token = $request->user()->currentAccessToken(); // 仅对持久化令牌执行删除操作 if (!$token instanceof \Laravel\Sanctum\TransientToken) { $token->delete(); } return response()->json([ 'message' => 'auth.signed_out_successfully' ]); }
方案2:调整测试代码规范
首先检查你的测试类是否引入了WithoutMiddleware trait,如果有则移除,或者明确设置仅排除非必要的中间件,避免auth:sanctum中间件失效导致走Session认证逻辑。
其次将登出请求调整为Laravel推荐的写法,用内置方法替代手动设置Header,避免解析异常:
// * 发起登出请求 $response = $this->withToken($token) ->deleteJson('/api/auth/sign_out'); $response->assertStatus(200);
withToken方法会自动生成规范的Authorization: Bearer xxxx头,deleteJson方法会自动设置Accept: application/json头,无需手动添加。
内容的提问来源于stack exchange,提问作者Ahmed Masoud
相关产品推荐
相关产品推荐

