Laravel 在AppServiceProvider中声明Oberserver时丢失Auth::user()
我试图在我的一个模型中使用本地作用域,但为此我需要检查用户权限,因此我尝试通过Auth::user()获取经过身份验证的用户 但是它给了我一个null,因为我为这个模型声明了一个观察者,如果我对观察者的声明进行注释,Auth::user()方法会给我一个经过身份验证的用户 有一个正确的方法或位置来声明观察者,并且在模型中我可以获得经过身份验证的用户,因为我需要使用观察者并在引导方法中获得经过身份验证的用户 Laravel框架6.5.2 AppServiceProvider在模型中无法进行身份验证Laravel 在AppServiceProvider中声明Oberserver时丢失Auth::user(),laravel,eloquent,Laravel,Eloquent,我试图在我的一个模型中使用本地作用域,但为此我需要检查用户权限,因此我尝试通过Auth::user()获取经过身份验证的用户 但是它给了我一个null,因为我为这个模型声明了一个观察者,如果我对观察者的声明进行注释,Auth::user()方法会给我一个经过身份验证的用户 有一个正确的方法或位置来声明观察者,并且在模型中我可以获得经过身份验证的用户,因为我需要使用观察者并在引导方法中获得经过身份验证的用户 Laravel框架6.5.2 AppServiceProvider在模型中无法进行身份验证
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Conciliador::observe(ConciliadorObserver::class);
Proposta::observe(PropostaObserver::class);
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//Conciliador::observe(ConciliadorObserver::class);
//Proposta::observe(PropostaObserver::class);
}
模型中的AppServiceProvider工作身份验证
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Conciliador::observe(ConciliadorObserver::class);
Proposta::observe(PropostaObserver::class);
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//Conciliador::observe(ConciliadorObserver::class);
//Proposta::observe(PropostaObserver::class);
}
在AppServiceProvider中声明Observer时,模型没有用户登录
/**
* The "booting" method of the model.
*
* @return void
*/
protected static function boot()
{
parent::boot();
$user = Auth::user();
dd($user); // null if Observer is declared in AppServiceProvider
if($user && $user->tipo == 'admin-gerenciador'){
$conciliadores = $user->conciliadores->pluck('id')->toArray();
static::addGlobalScope('Conciliadores', function (Builder $builder) {
$builder->whereIn('id',$conciliadores);
});
}
}
您不应该在模型的引导方法中这样做。对于模型,
boot
方法只调用一次,而不是针对每个模型实例。第一次使用该模型时,boot
将被调用,这将是在您的案例中的服务提供商中为其添加观察者时;在请求被发送到路由并通过中间件堆栈之前,这将是一种方式。(此时没有会话,因此没有经过身份验证的用户。)
您可能希望通过中间件将全局范围添加到模型中。- 不要在任何地方调用
。它可能会触发身份验证的副作用。强烈建议仅在控制器和中间件中执行此操作Auth::user()
- 但是,如果您事先通过
进行检查,则可以安全地调用Auth::hasUser()
;它检查用户是否已通过身份验证Auth::user()
/**
* The "booting" method of the model.
*/
protected static function boot(): void
{
static::addGlobalScope('Conciliadores', function (Builder $query) {
if (Auth::hasUser() && Auth::user()->tipo === 'admin-gerenciador') {
$query->whereKey(Auth::user()->conciliadores->modelKeys());
}
});
}
这是一个非常简单的解决方案。甚至中间件也是不必要的
编辑
此范围始终可用,但实际上只有在用户已通过身份验证时才应用条件您使用的是哪个版本的Laravel?Laravel Framework 6.5.2@Chinleung您能给我一个使用中间件的示例吗@lagboxThankyu@mpyw,但在代码通过AppServiceProvider上的引导方法传递并拥有登录用户之后,我需要将作用域应用于模型。如何做到这一点?您是否更喜欢“仅在身份验证后应用的每个用户的全局范围”而不是“始终应用的仅用于已验证用户的全局范围”?我认为它们的行为方式完全相同,但您敢选择复杂的实现吗?