返回

如何在 Laravel Fortify 中配置自定义守卫和单元测试

php

为 Laravel 中的 Fortify 守卫配置自定义路由和单元测试

简介

Laravel Fortify 是一个一站式身份验证系统,提供了用于用户注册、登录和密码重置的预定义路由和视图。但是,在某些情况下,你可能需要为不同的路由或单元测试指定不同的守卫。本文将探讨如何实现这一点。

动态守卫配置的挑战

在示例代码中,我们定义了一个中间件,用于根据请求的路由动态设置 Fortify 守卫。这在应用程序中可能有效,但在单元测试期间却会导致问题,因为 request() 助手返回的是 GET /,而不是预期路由。

解决方案:自定义守卫

Laravel 提供了一种优雅的方法来配置 Fortify 守卫,而无需依赖中间件或动态更改配置。我们可以通过以下步骤实现此目的:

1. 定义自定义守卫:

config/auth.php 配置文件中定义一个自定义守卫,指定要使用的用户模型和提供者。例如:

'guards' => [
    'admin' => [
        'driver' => 'session',
        'provider' => 'admins',
        'model' => App\Models\Admin::class,
    ],
],

2. 配置路由:

routes/api.php 路由文件中,使用 auth 中间件为受保护的路由指定自定义守卫。例如:

Route::group(['middleware' => ['auth:admin']], function () {
    // 管理员专用路由
});

3. 单元测试:

在单元测试中,可以使用 ActingAs 特性来模拟特定守卫下的认证用户。例如:

use Illuminate\Foundation\Testing\Concerns\InteractsWithAuthentication;

class ExampleTest extends TestCase
{
    use InteractsWithAuthentication;

    public function testAdminLogin()
    {
        $this->actingAs(Admin::find(1)); // 模拟管理员登录

        // 断言对受保护的管理员路由的请求成功
    }
}

优点

这种方法具有以下优点:

  • 简洁性: 消除了对中间件或动态配置更改的需要。
  • 可测试性: 简化了在不同守卫下模拟认证用户的单元测试。
  • 可维护性: 有助于保持代码整洁和易于维护。

结论

通过使用自定义守卫和 ActingAs 特性,我们可以在 Laravel Fortify 中为不同的路由和单元测试轻松配置守卫。这提供了更大的灵活性,并简化了应用程序的身份验证逻辑。

常见问题解答

1. 我可以为一个路由组定义多个守卫吗?

是的,可以使用 auth:guard1|guard2|... 语法为路由组指定多个守卫。

2. 如何在中间件中动态设置守卫?

虽然不建议这样做,但你可以使用 auth()->setDefaultDriver() 在中间件中动态设置默认守卫。

3. 如何使用自定义守卫执行身份验证?

使用 Auth::guard('custom-guard')->attempt() 来使用自定义守卫执行身份验证。

4. 如何在单元测试中使用多个守卫?

可以使用 ActingAs 特性多次执行 actingAs() 方法来模拟不同守卫下的认证用户。

5. 如何避免因不同的守卫导致的单元测试错误?

确保在测试方法中设置正确的默认守卫,并使用 ActingAs 特性来模拟所需的守卫。