【问题标题】:Laravel Sanctum custom guardLaravel Sanctum 自定义守卫
【发布时间】:2021-06-19 22:33:47
【问题描述】:

我的 laravel 应用程序中有多个守卫:

代码 config/auth.php:

'defaults' => [
    'guard' => 'user',
    'passwords' => 'users',
],

'guards' => [
    'user' => [
        'driver' => 'token',
        'provider' => 'users',
        'hash' => true,
    ],
    'admin' => [
        'driver' => 'token',
        'provider' => 'admins',
        'hash' => true,
    ]
],

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => User::class,
    ],
    'admins' => [
        'driver' => 'eloquent',
        'model' => Admin::class,
    ],
],

'passwords' => [
    'users' => [
        'provider' => 'users',
        'table' => 'users_password_resets',
        'expire' => 60,
        'throttle' => 60,
    ],
    'admins' => [
        'provider' => 'admins',
        'table' => 'admins_password_resets',
        'expire' => 60,
        'throttle' => 60,
    ],
],

'password_timeout' => 10800,

并且有在api.php 中获取认证用户的路径:

Route::get('admins/auth/user', 'AuthController@user')->middleware('auth:sanctum');

在我的模型(管理员、用户)中也使用了 trait:

Laravel\Sanctum\HasApiTokens

当我尝试通过令牌获取身份验证用户时,会出现错误消息:

InvalidArgumentException: Auth guard [web] is not defined. in file appname\vendor\laravel\framework\src\Illuminate\Auth\AuthManager.php on line 84

#0 appname\vendor\laravel\framework\src\Illuminate\Auth\AuthManager.php(68): Illuminate\Auth\AuthManager->resolve()
#1 appname\vendor\laravel\sanctum\src\Guard.php(45): Illuminate\Auth\AuthManager->guard()
#2 [internal function]: Laravel\Sanctum\Guard->__invoke()
#3 appname\vendor\laravel\framework\src\Illuminate\Auth\RequestGuard.php(58): call_user_func()
#4 appname\vendor\laravel\framework\src\Illuminate\Auth\GuardHelpers.php(60): Illuminate\Auth\RequestGuard->user()
#5 appname\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php(63): Illuminate\Auth\RequestGuard->check()
#6 appname\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php(42): Illuminate\Auth\Middleware\Authenticate->authenticate()

我已经运行了命令:

php artisan cache:clear
php artisan config:cache

还尝试将警卫名称添加到config/sanctum.php

'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1')),

'expiration' => null,

'middleware' => [
    'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
    'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
],

// This line added
'guard' => 'admin'

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    我解决了类似的问题,因为我对用户和管理员用户使用身份验证。 您可以使用 sanctum 使用中间件('auth: sanctum')通过 laravel / ui 包对自己进行身份验证,但要使其使用 ADMIN 模型而不是 USER,您必须更改警卫。 让我解释一下:sanctum 通常是 auth 中定义的守卫,'web' 和 'api' 也是如此,默认情况下 auth.guards.sanctum 的 provider = null。所以我所做的就是定义我自己的守卫:

    'providers' => [
    'admin' => [
                'driver' => 'sanctum',
                'provider' => 'admins',
            ],
    ],
    
    'providers' => [
    'admins' => [
                'driver' => 'eloquent',
                'model' => App \ Models \ Admin :: class,
            ],
    ],
    

    您可以使用中间件保护您的路线('auth: sanctum') 并且通过这种方式,您使用的是 Admin 模型而不是 User 模型。 每次调用您使用 auth: sanctum 保护的组内的路由时,此 auth.guard 将绑定到 providers.admins,这将始终验证 Admin 模型。

    你会遇到的问题是当你登录时,你必须定义你登录时要使用的守卫,因为如果你使用 laravel / ui 包,它默认使用守卫。 web 并且这将关联 User 模型,尽管在 User 模型中有一个具有相同凭据的用户,但当他访问受 sanctum 保护的路径时,他将使用 Admin 模型验证凭据。 所以诀窍是,在登录时,强制将守卫更改为具有提供程序 Admin 的守卫。 就我而言,我所做的是创建一个中间件,它所做的是更改guards.web 的提供者 创建中间件,我在routeMiddleware的kernel.php文件中注册了,这样放:

    'auth.admin' => \ App \ Http \ Middleware \ AuthenticateGuardAdmin :: class,
    

    并且中间件包含在这行代码中: Config :: set ('auth.guards.web.provider', 'admins');

    还有我放在这里的中间件:

    Route :: middleware ('auth.admin') -> group (function () {
        Auth :: routes (['register' => false]);
        Route :: middleware ('auth: sanctum') -> group (function () {
            Route :: get ('/ home', 'HomeController @ index') -> name ('home');
        });
    });
    

    在使用 laravel / ui 包的标准控制器登录时,我已经告诉配置变量将使用的提供程序将是我定义的使用 Admin 模型的提供程序。 有了这个,登录、身份验证和授权总是使用 Admin 模型完成。

    之后,您甚至可以使用其他身份验证定义和其他模型或相同的默认用户模型创建其他路由组,甚至使用 API 路由或 Web 路由中的 sanctum。

    【讨论】:

    • 看不懂Config::set('auth.guards.web.provider', 'admins');这行代码在哪里用,是哪个文件
    【解决方案2】:

    对我来说,在 config/sanctum.php 文件中添加保护解决了我的问题。

    'guard' => 'admin'
    

    你可以在这里看到配置是如何被圣殿的守卫在这里使用的。

    https://github.com/laravel/sanctum/blob/2.x/src/Guard.php#L55

    您也可以根据上面的代码传递一个值数组,因为配置是由Arr::wrap包装的

    【讨论】:

      猜你喜欢
      • 2021-05-01
      • 2019-07-20
      • 2021-01-12
      • 2019-09-30
      • 2022-07-06
      • 1970-01-01
      • 2021-10-01
      • 2016-04-26
      • 2021-07-02
      相关资源
      最近更新 更多