Laravel: как использовать ворота с несколькими охранниками

У меня есть традиционное веб-приложение, которое имеет несколько разных типов пользователей, и каждый тип пользователя имеет свою собственную защиту аутентификации.

'guards' => [

    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'admin' => [
        'driver' => 'session',
        'provider' => 'admin',
    ],
    'timekeeper' => [
        'driver' => 'session',
        'provider' => 'timekeeper',
    ],
    'api' => [
        'driver' => 'token',
        'provider' => 'users',
    ],
],

Большинство моих пользователей аутентифицируются с помощью «веб-защиты», однако администраторы и хронометристы используют свою собственную защиту, которая привязана к соответствующему провайдеру пользователей.

Это нормально, пока я не попытаюсь использовать шлюзы аутентификации. Если я аутентифицирую пользователя с помощью защиты системы по умолчанию (например, «веб»), то ворота работают должным образом. Однако, если я аутентифицируюсь против любого другого охранника, все вызовы Gate::allows(...) ОТКЛОНЯЮТСЯ.

Отказано даже в следующей способности:

Gate::define('read', function ($user) {
    return true;
});

Предположительно это связано со строкой 284-286 в Illuminate\Auth\Access\Gate:

if (! $user = $this->resolveUser()) {
    return false;
}

Насколько я вижу, мои варианты:

  • Вернитесь к использованию единого «веб-защиты» с поставщиком пользователей, который может найти пользователя любого типа (но я не уверен, как это будет работать, если я начну использовать API параллельно)
  • Как-то установить защиту по умолчанию во время выполнения, в зависимости от типа текущего пользователя. (В настоящее время он установлен в файле конфигурации)
  • Каким-то образом внедрить другой преобразователь пользователя в фасад Gate (опять же, в зависимости от типа текущего пользователя)

Однако ни один из них не кажется интуитивно понятным. Я что-то упускаю?


person DatsunBing    schedule 16.01.2018    source источник


Ответы (1)


Это не самое элегантное решение, потому что оно требует много дополнительного стандартного кода, но вы можете использовать Gate::forUser($user)->allows() вместо Gate::allows(), где $user происходит от Auth::guard().

person Moshe Katz    schedule 16.01.2018
comment
Работая с этим ответом, я реализовал вспомогательную функцию для уменьшения шаблона и доволен результатом. - person DatsunBing; 07.02.2018