Шлюз авторизации не вызывается во время предоставления услуг - PullRequest
1 голос
/ 10 апреля 2019

В моем AuthServiceProvider определен вентиль admin, который используется для добавления глобальных областей запросов к некоторым моделям.Предположим, у меня были модели A, наблюдаемые Observer (зарегистрированными в AppServiceProvider) и B, использующие вентиль admin для добавления глобальных областей запросов.

// app/Providers/AuthServiceProvider.php
class AuthServiceProvider extends ServiceProvider
{
  public function boot()
  {
    Gate::define('admin', [static::class, 'admin']);
  }

  public static function admin(User $user): bool
  {
    return $user->group->name === 'Admin';
  }
}
// app/B.php
class B extends Eloquent
{
  public static function boot()
  {
    parent::boot();

    if (!Gate::allows('admin')) {
      static::addGlobalScope('public', function ($query) {
        $query->where('public', true);
      });
    }
  }
}

До этого момента все работало нормально.Затем я добавил модель C, которая имеет Observer и использует ворота admin.Поскольку C::observe() запускает C::boot() и AppServiceProvider регистрируется до AuthServiceProvider, ворота не были определены, и я извлек регистрацию Observer в новый ObserverServiceProvider, который зарегистрирован после AuthServiceProvider.

// app/C.php
class C extends Eloquent
{
  public static function boot()
  {
    parent::boot();

    if (!Gate::allows('admin')) {
      static::addGlobalScope('public', function ($query) {
        $query->where('public', true);
      });
    }
  }
}
// app/Providers/ObserverServiceProvider.php
class ObserverServiceProvider extends ServiceProvider
{
  public function boot()
  {
    A::observe(AObserver::class);
    C::observe(CObserver::class);
  }
}
// config/app.php
'providers' => [
  //...
  App\Providers\AppServiceProvider::class,
  App\Providers\AuthServiceProvider::class,
  //...
  App\Providers\ObserverServiceProvider::class,
]

Моя проблема:

Наблюдатели для A и C все еще работают, а также вход admin вB boot(), но Gate::allows('admin') в C всегда возвращает false даже без вызова функции gate.

Добавление var_dump(Gate::has('admin')) в C::boot() выходных данных true ииспользование @can('admin') позже в View во время того же запроса также работает нормально, поэтому шлюз определенно определен и работает в принципе.

1 Ответ

0 голосов
/ 10 апреля 2019

Шлюз авторизации не может быть вызван, поскольку данные сеанса (и, следовательно, аутентифицированный пользователь) становятся доступными промежуточным программным обеспечением StartSession, которое работает после поставщиков услуг.

Проблема может быть решена путем установкипроверка Gate::allows() внутри анонимной функции, поэтому она выполняется только при построении запроса:

// app/C.php
class C extends Eloquent
{
  public static function boot()
  {
    parent::boot();

    static::addGlobalScope('public', function ($query) {
      if (!Gate::allows('admin')) {
        $query->where('public', true);
      }
    });
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...