Laravel路由中间件用Policy时PHPUnit测试跳转登录如何解决
问题根因
你遇到的302跳转是因为can授权中间件默认使用web守卫获取当前登录用户,而你使用Passport::actingAs()生成的登录态仅对api守卫生效:
- 中间件拿不到
api守卫的用户身份,触发未认证逻辑 - 未指定请求为JSON类型时,Laravel默认未认证响应就是跳转到登录页(302),所以请求没有进入控制器就被拦截了
解决方法
1. 给API路由补充auth:api前置中间件
优先验证api守卫的登录状态,未登录时直接返回401而非302跳转,之后再走授权校验:
Route::post('/posts/{post:reference}/editDetails', [PostDetailsApiController::class, 'update']) ->middleware('auth:api', 'can:update,post');
2. (可选)直接给can中间件指定守卫
如果不想单独加auth:api,也可以直接给can中间件传第三个参数指定使用api守卫:
Route::post('/posts/{post:reference}/editDetails', [PostDetailsApiController::class, 'update']) ->middleware('can:update,post,api');
3. 测试时指定JSON请求头
单元测试时加上Accept: application/json头,确保Laravel在异常场景下返回JSON响应而非跳转:
$this->user = User::factory()->create(); $post = Post::factory()->create(['user_id' => $this->user->id]); Passport::actingAs($this->user); $response = $this->withHeaders(['Accept' => 'application/json']) ->post('/api/posts/' . $post->reference . '/editDetails'); $response->assertStatus(200);
内容的提问来源于stack exchange,提问作者jkstallard
相关产品推荐
相关产品推荐

