我目前正在为我的路线开发单元测试,我遇到了一个奇怪的情况。
我在routes/fortify.php 文件中创建了一些路由。
其中一些路由使用另一个 fortify.guard(管理员和用户无权访问相同的页面)。
为了做到这一点,我在 FortifyServiceProvider 类中编写了以下内容:
/**
* Register any application services.
*/
public function register(): void
{
Fortify::ignoreRoutes();
if(request()->is('api/v1/admin/*')){
config()->set('fortify.guard', 'admin');
}
}
现在,当我运行
php artisan test
时,它不再起作用,因为 request()
的路线是 GET / (我不知道为什么。)
请参阅下面我的测试代码:
public function loginAsTestAdmin(): void
{
$payload = ['email' => '[email protected]', 'password' => bcrypt('password')];
$this->post('api/v1/admin/login', $payload)->assertStatus(200);
}
调用此路由时,
if(request()->is('api/v1/admin/*'))
测试失败,因此,警卫尝试检索数据库中的模型用户而不是模型管理员,并最终导致身份验证失败(因为用户的电子邮件地址为“[电子邮件受保护]”) ' 不存在)。
所以,我发现动态更改配置来设置正确的防护可能不是 Laravel 的做法。
我应该如何声明我的路线以便他们使用正确的警卫?
也许在 config/auth.php 中有类似的东西
'guards' => [
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
在routes/fortify.php中:
Route::middleware(['auth:admin'])->group(function () {
// routes protected by the admin guard, for example
Route::post('api/v1/admin/login', [\App\Http\Controllers\AdminLoginController::class, 'login']);
});
Route::middleware(['auth'])->group(function () {
// routes protected by the default guard or user guard
});
这样你就不必动态改变守卫,你只需为每条路线或一组路线指定守卫即可。