简体   繁体   中英

running laravel horizon in production throw a 403 error when requesting domain/horizon

I have testet laravel Horizon on my local environment and everything is working as expected. When I am switching to production domain/horizon throws a 403 error. I have set the gate in HorizonServiceProvider as stated in the documentation - First step is just to get access without auth. My gate now looks like this:

{
    Gate::define('viewHorizon', function ($user = null) {
        return true;
    });
}

Can anyone suggest what I am missing?

link to 403 error link to 401 error - Dashboard without data

Check this GitHub comment: https://github.com/laravel/horizon/issues/563#issuecomment-480882947

You may have to register Horizon's service provider.

In config/app.php :

'providers' => [
        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
    ...
        App\Providers\TelescopeServiceProvider::class,
        App\Providers\HorizonServiceProvider::class,
    ],

The error it's because horizon it's first go to the boot method, so i recommended you in your HorizonServiceProvider.php edit the boot method to allow your request like this:

 /** * Bootstrap any application services. * * @return void */ public function boot() { parent::boot(); Horizon::auth(function ($request) { if ($request->ajax()){ return true; } else if (isset($request->let_me_go) && $request->let_me_go == 'ok'){ return true; }else{ throw new UnauthorizedHttpException('Unauthorized'); } }); }

So when you will go to your production server need to pass the parameter like this:

my-production-site.com/horizon/dashboard?let_me_go=ok

You need to add the following method to App\Providers\HorizonServiceProvider class:

class HorizonServiceProvider extends ServiceProvider {
    
    // ...

    protected function authorization()
    {
        Horizon::auth(function () {
            return true;
        });
    }
}

This method overrides the parent method that authenticates HTTP requests.

For me, the problem was that I'd set in app\Providers\HorizonServiceProvider.php :

/**
 * Register the Horizon gate.
 *
 * This gate determines who can access Horizon in non-local environments.
 *
 * @return void
 */
protected function gate() {
    Gate::define('viewHorizon', function ($user) {//https://laravel.com/docs/7.x/horizon#dashboard-authorization            
        return $user->id === \App\Constants\Permissions::ADMIN_USER_ID;
    });
}

And then I'd forgotten that I'd therefore need to log in at example.com/login before I'd be allowed to visit example.com/horizon.

See https://github.com/laravel/horizon/issues/563#issuecomment-500821983 and https://laravel.com/docs/8.x/horizon#dashboard-authorization

Removing the second parameter [$request->user()] in the authorization() method allowed the Gate check() to execute. Otherwise, it was always returning false no matter what was inside the define() function

/**
 * Configure the Horizon authorization services.
 *
 * @return void
 */
protected function authorization()
{
    $this->gate();

    Horizon::auth(function ($request) {
        return Gate::check('viewHorizon', []) ||
            app()->environment('local');
    });
}

/**
 * Register the Horizon gate.
 *
 * This gate determines who can access Horizon in non-local environments.
 *
 * @return void
 */
protected function gate()
{
    Gate::define('viewHorizon', function ($user = null) {
        return $user->isAdmin();
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM