Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Laravel 在AppServiceProvider中声明Oberserver时丢失Auth::user()_Laravel_Eloquent - Fatal编程技术网

Laravel 在AppServiceProvider中声明Oberserver时丢失Auth::user()

Laravel 在AppServiceProvider中声明Oberserver时丢失Auth::user(),laravel,eloquent,Laravel,Eloquent,我试图在我的一个模型中使用本地作用域,但为此我需要检查用户权限,因此我尝试通过Auth::user()获取经过身份验证的用户 但是它给了我一个null,因为我为这个模型声明了一个观察者,如果我对观察者的声明进行注释,Auth::user()方法会给我一个经过身份验证的用户 有一个正确的方法或位置来声明观察者,并且在模型中我可以获得经过身份验证的用户,因为我需要使用观察者并在引导方法中获得经过身份验证的用户 Laravel框架6.5.2 AppServiceProvider在模型中无法进行身份验证

我试图在我的一个模型中使用本地作用域,但为此我需要检查用户权限,因此我尝试通过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上的引导方法传递并拥有登录用户之后,我需要将作用域应用于模型。如何做到这一点?您是否更喜欢“仅在身份验证后应用的每个用户的全局范围”而不是“始终应用的仅用于已验证用户的全局范围”?我认为它们的行为方式完全相同,但您敢选择复杂的实现吗?