服务提供商期间未调用授权门

时间:2019-04-10 15:49:22

标签: php laravel-5 laravel-5.8

我在admin中定义了一个AuthServiceProvider门,用于将全局查询范围添加到某些模型。假设我有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注册提取到新的{{1} }在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的{​​{1}}方法中的admin门仍在工作,但是{{1 B中的}}始终返回boot(),甚至不调用gate函数。

Gate::allows('admin')输出中添加C输出false,并在同一请求期间稍后在var_dump(Gate::has('admin'))中使用C::boot()也可以正常工作,因此门是明确定义且原则上可行。

1 个答案:

答案 0 :(得分:0)

由于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);
      }
    });
  }
}