Laravel Sanctum 自定义守卫

And*_*ter 8 php laravel

我的 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,
Run Code Online (Sandbox Code Playgroud)

并有获取经过身份验证的用户的路线api.php

Route::get('admins/auth/user', 'AuthController@user')->middleware('auth:sanctum');
Run Code Online (Sandbox Code Playgroud)

另外在我的模型(管理员,用户)中使用了特征:

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()
Run Code Online (Sandbox Code Playgroud)

我已经运行过命令:

php artisan cache:clear
php artisan config:cache
Run Code Online (Sandbox Code Playgroud)

还尝试将守卫名称添加到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'
Run Code Online (Sandbox Code Playgroud)

小智 7

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

'providers' => [
'admin' => [
            'driver' => 'sanctum',
            'provider' => 'admins',
        ],
],

'providers' => [
'admins' => [
            'driver' => 'eloquent',
            'model' => App \ Models \ Admin :: class,
        ],
],
Run Code Online (Sandbox Code Playgroud)

并且您可以使用中间件(“auth: sainttum”)保护您的路由,这样您将使用管理模型而不是用户模型。每次调用您使用 auth: sainttum 保护的组内的路由时,此 auth.guard 都会将其绑定到providers.admins,这将始终验证管理模型。

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

'auth.admin' => \ App \ Http \ Middleware \ AuthenticateGuardAdmin :: class,
Run Code Online (Sandbox Code Playgroud)

中间件包含这行代码: 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');
    });
});
Run Code Online (Sandbox Code Playgroud)

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

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


小智 5

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

'guard' => 'admin'
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看圣所守卫如何使用该配置。

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

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