我在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()
也可以正常工作,因此门是明确定义且原则上可行。
答案 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);
}
});
}
}