Closed windows1087 closed 5 years ago
Can you please fill out the issue template?
You 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,
],
Hi there,
Thanks for reporting but it looks like this is a question which can be asked on a support channel. Please only use this issue tracker for reporting bugs with the library itself. If you have a question on how to use functionality provided by this repo you can try one of the following channels:
Thanks!
I had the same problem (Laravel 5.8, Horizon 3.2.2)
My issue was this default code in the published HorizonServiceProvider
:
Gate::define('viewHorizon', function ($user) {
return true;
});
In my case I've no auth middleware because it's done on the webserver already via IP-addresses matching VPN, etc.
So, no authenticated user present.
However: when defining the closure like this function ($user) {… }
and there is no authenticated user, this gate is entirely skipped because of this code https://github.com/laravel/framework/blob/9b7520a2ac0009d4c1ff2322e3ef673ef702e7e2/src/Illuminate/Auth/Access/Gate.php#L527-L528
The canBeCalledWithUser
performs PHP reflection on the closure and if there's no auth user but $user
is present, it will not execute the gate.
The solution: change the closure to have user optional: function ($user = null) { … }
@mfn might be worth a pr to the docs if you have some time :)
解决方案:更改闭包以使用户可选: function ($user = null) { … } Official Repair to Reduce User Difficulty
Docs PR submitted: https://github.com/laravel/docs/pull/5351
It is possible that you are not using the default guard。change the default guard in config/auth.php
such as
'defaults' => [
'guard' => 'admin',
'passwords' => 'front_users',
],
I had the same problem (Laravel 5.8, Horizon 3.2.2)
My issue was this default code in the published
HorizonServiceProvider
:Gate::define('viewHorizon', function ($user) { return true; });
In my case I've no auth middleware because it's done on the webserver already via IP-addresses matching VPN, etc.
So, no authenticated user present.
However: when defining the closure like this
function ($user) {… }
and there is no authenticated user, this gate is entirely skipped because of this code https://github.com/laravel/framework/blob/9b7520a2ac0009d4c1ff2322e3ef673ef702e7e2/src/Illuminate/Auth/Access/Gate.php#L527-L528The
canBeCalledWithUser
performs PHP reflection on the closure and if there's no auth user but$user
is present, it will not execute the gate.The solution: change the closure to have user optional:
function ($user = null) { … }
This solution worked . I am using Auth::guard('guard')->user().
Thanks.
I am using a non-default guard since my default guard is for my API and uses JWT tokens. So I had some trouble getting this to work correctly. In the end this is what works:
I created a login form using laravel/ui, but I am using a custom login controller which looks like this:
$credentials = $request->only('email', 'password');
if (auth()->guard('web')->attempt($credentials)) {
return redirect()->intended('home');
}
Then in my horizon.php config I set this for my middlewares:
'middleware' => ['web', 'auth:web'],
Note that I specify that the auth middleware should use the web guard since that is not the default
And finally in my HorizonServiceProvider I have this
Gate::define('viewHorizon', function ($user = null) {
return in_array(\Auth::guard('web')->user()->email, [
'example@gmail.com',
]);
});
You 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, ],
Thank you! This took me hours to find. I don't think it's in the docs, and I don't know why.
@ryancwalsh that's because these lines get added when you run php artisan horizon:install
so the docs just assume you will run this command
@vesper8 That's not my experience. I've run php artisan horizon:install
multiple times (and even just tried it again after reverting my manual changes to config/app.php
), and my config/app.php
does not mention Horizon at all unless I add App\Providers\HorizonServiceProvider::class,
manually.
@ryancwalsh could it be that your config file is customized to a degree that the installer can't find the anchors it's trying to install against?
ie: it adds its content by doing a string replacement, but must find the string in the first place: https://github.com/laravel/horizon/blob/3.0/src/Console/InstallCommand.php
@drbyte Interesting. No, I think my config/app.php
looks pretty normal. I see App\Providers\EventServiceProvider::class,
in mine, which is what https://github.com/laravel/horizon/blob/3.0/src/Console/InstallCommand.php#L63 seems to be looking for. The double backslashes \\
aren't intuitive to me, but I assume that file has those intentionally.
I am using a non-default guard since my default guard is for my API and uses JWT tokens. So I had some trouble getting this to work correctly. In the end this is what works:
I created a login form using laravel/ui, but I am using a custom login controller which looks like this:
$credentials = $request->only('email', 'password'); if (auth()->guard('web')->attempt($credentials)) { return redirect()->intended('home'); }
Then in my horizon.php config I set this for my middlewares:
'middleware' => ['web', 'auth:web'],
Note that I specify that the auth middleware should use the web guard since that is not the default
And finally in my HorizonServiceProvider I have this
Gate::define('viewHorizon', function ($user = null) { return in_array(\Auth::guard('web')->user()->email, [ 'example@gmail.com', ]); });
Specifying auth:web
in the horizon config is what I was missing. I also realized the HorizonServieProvider
wasn't added automatically to config/app.php
Since web
wasn't my default auth guard. Thanks
I also ran into not having HorizonServiceProvider installed. My app initially integrated with Horizon 1.0, which does not seem to require this, and the upgrade guide to v3 did not mention it.
The other gotcha I ran into was needing to change the default production PHP 7.4 php.ini to allow pcntl_async_signals, pcntl_alarm, and pcntl_signal.
In config/app.php
:
'providers' => [
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
...
...
App\Providers\RouteServiceProvider::class,
App\Providers\HorizonServiceProvider::class
],
HorizonServiceProvider
must always be listed after RouteServiceProvider
to make gate()
work correctly.
APP_ENV!=local to make gate() work correctly. APP_ENV=production
I can confirm this worked for me:
Gate::define('viewHorizon', function ($user = null) {
$u = Auth::guard('web')->user();
return in_array($u->email, [
'my@email.com'
]);
});
...combining the null user and then manually setting the guard.
You 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, ],
I would have thought this was done automatically in 2023, but it turns out I still had to add it manually. Maybe because I am using an unusual setup - Laravel Splade JetStream
@taylorotwell can you confirm that we should add HorizonServiceProvider to the config/app.php (this part is missing in the documentation)?
You 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, ],
I already registered this, but I am still get problem with ALL requests to backend (they returns 403 error), with this text:
Problem reproduced only on prod server and on local I cant to get this error. And I dont understand what is the problem. Maybe somebody knows?
Also I am already rewrite gate() function in app/Providers/HorizonServiceProvider.php , bit it doesn`t helps
Lara 9, php 8.1 local, php8.2 server;
I can not make it start to work. This protected horizon route with checking the user email is not working for me on php 8.2.
"laravel/framework": "^10.3.0",
"laravel/horizon": "^5.21",
it seems like I never access viewHorizon closure:
protected function gate(): void
{
Gate::define('viewHorizon', function ($user = null) {
dd('test');
dd($user);
return in_array($user->email, config('test.horizon_auth_emails'));
});
}
still receive Forbidden for all users
Hi there!
In the beginning you should check that in your .env file environment variable APP_ENV=production or gate will won't to work.
Here is the way how I can solved it:
in config/auth.php
you need to change the default guard from api
to e.g. web
:
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
the next step is to change the gate function like I did (note that $user should be nullable):
protected function gate(): void
{
Gate::define('viewHorizon', function ($user = null) {
return Auth::guard('moonshine')->user()->hasRole("Admin");
});
}
don't forget to change guard to your own.
On my other project gate wants to work, seems like Gate::define not working, I'm solved problem by checking a role for user in the authorization function to:
/**
* @return void
*/
protected function authorization(): void
{
Horizon::auth(function ($request) {
return Auth::user()->hasRole('your_role_here');
});
}
I'm using Laravel 5.7 with Horizon.
It works in
local
, but if i setproduction
in my .env file on our server, it gives me the 403 status code.This is my service provider:
Do i need to register this gate somewhere? I'm logged in as a user on my application.