繁体   English   中英

Laravel 圣所海关守卫

[英]Laravel Sanctum custom guard

我的 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');

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

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'

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

'guard' => 'admin'

您可以在此处查看 sanctum 的守卫如何使用配置。

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

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

我解决了类似的问题,因为我对用户和管理员用户使用身份验证。 您可以使用 sanctum 使用中间件 ('auth: sanctum') 使用 laravel / ui package 对自己进行身份验证,但要使用 ADMIN Z20F35E630DAF44DBFA4C3F68FC,您必须更改警卫,而不是 USERD8Z3 让我解释一下: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')保护您的路线,这样您就可以使用管理员 model 而不是用户 model。 每次调用您使用 auth: sanctum 保护的组内的路由时,此 auth.guard 将绑定到 providers.admins,这将始终验证 Admin model。

您将遇到的问题是登录时,您必须定义登录时要使用的防护,因为如果您使用 laravel / ui package,默认情况下使用防护。 web and this will associate the User model, and although there is a user with the same credentials in the User model, when he accesses the paths protected with sanctum, he will verify the credentials with the Admin model. 所以诀窍是,在登录时,强制将守卫更改为具有提供者 Admin 的守卫。 在我的情况下,我所做的是创建一个中间件,它所做的是更改警卫的提供者。web 创建中间件,我在 kernel.ZE1BFD762321E409CEE4AC0B6E841963 中注册了它,就像这样:CEE4AC0B6E841963

'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 package 的标准控制器登录时,我已经告诉配置变量,将使用的提供程序将是我定义的使用管理员 Z20F35E630DAF49DF85CZ3 的提供程序。 有了这个,登录、身份验证和授权总是由管理员 model 完成。

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

使用sanctum驱动程序定义API sanctum 守卫

'guards' => [
        // Web Guards
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        //API Sanctum Guards
        'admin-api' => [
            'driver' => 'sanctum',
            'provider' => 'admins',
        ],
        'vendor-api' => [
            'driver' => 'sanctum',
            'provider' => 'vendors',
        ],
    ],

定义供应商

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],
    'admins' => [
        'driver' => 'eloquent',
        'model' => App\Models\Admin::class,
    ],
    'vendors' => [
        'driver' => 'eloquent',
        'model' => App\Models\Vendor::class,
    ],
],

生成令牌

$user = Admin::where('email', $request->email)->first();
$token = $user->createToken(uniqid());
return ['token' => $token->plainTextToken];


$user = Vendor::where('email', $request->email)->first();
$token = $user->createToken(uniqid());
return ['token' => $token->plainTextToken];

使用sanctum guard保护路线

Route::middleware('auth:admin-api')->get('/admin', function (Request $request) {
    return $request->user();
});

Route::middleware('auth:vendor-api')->get('/vendor', function (Request $request) {
    return $request->user();
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM