Laravel 5.7测试中actingAs设置用户后auth()->user()->id为null的解决方法
解决Laravel 5.7测试中控制器无法获取认证用户的问题
看起来你遇到的问题主要来自两个关键点:用户未持久化到数据库,以及认证 Guard 的匹配问题。我来一步步帮你调整测试和代码:
1. 修正测试中的用户创建方式
你当前用make()方法生成用户,这只会创建内存中的模型实例,不会保存到数据库。而Laravel的认证系统(尤其是Eloquent驱动的Guard)需要用户存在于数据库中才能正确识别,这就是控制器里auth()->user()返回null的核心原因之一。
把测试里的make()改成create():
/** @test */ public function do_nothing_test() { // 用create()替代make(),将用户保存到数据库 $user = factory(User::class)->states('app')->create(); $this->actingAs($user, 'api'); $response = $this->postJson('some_endpoint', ['foobar' => 3]); $this->assertEquals(1, Foobar::count()); }
2. 修复控制器方法的请求参数
你的控制器方法参数$request没有类型提示,Laravel无法自动注入Request实例,这可能导致$request->foobar也无法正确获取值。修正控制器代码:
use Illuminate\Http\Request; // 记得引入Request类 public function update_foobar(Request $request) { $userId = auth()->user()->id; Foobar::create(['userId' => $userId, 'foobar' => $request->foobar]); }
3. 匹配认证Guard与路由中间件
你在测试中用了actingAs($user, 'api')指定api Guard,但如果你的路由没有配置auth:api中间件,控制器里默认的auth()会使用web Guard,自然找不到api Guard下的认证用户。
检查你的路由配置,确保接口路由使用auth:api中间件:
// 根据你的路由文件调整,比如routes/api.php或routes/web.php Route::post('some_endpoint', 'YourController@update_foobar')->middleware('auth:api');
如果不想在路由里指定api Guard,也可以在控制器里明确指定使用api Guard获取用户:
// 控制器里直接指定api Guard $userId = auth('api')->user()->id;
额外检查:确认api Guard配置
最后可以检查下config/auth.php里的api Guard配置,确保provider指向正确的用户模型:
'guards' => [ 'api' => [ 'driver' => 'token', // 若使用Passport可改为passport 'provider' => 'users', // 确保该provider对应你的User模型 ], ],
按照这几步调整后,控制器应该就能正确获取到认证用户的ID了。
内容的提问来源于stack exchange,提问作者GluePear
相关产品推荐
相关产品推荐

