larastan
larastan copied to clipboard
`FormRequest::user()`always returns the model of default guard
- Larastan Version: 2.1.4
-
--level
used: 9 - Pull request with failing test:
Description
It seems like FormRequest::user()
method is stated to return the model of default guard, even though multiple guards defined in the config/auth.php
.
Providing the name of the (non-default) guard with the method argument won't help; the method is still predicted to return the default.
Laravel code where the issue was found
Let's say the default guard is default_user
and model is \App\Models\DefaultUser
.
class ExampleRequest extends FormRequest
{
public function authorize(): bool
{
return $this->user() instanceof \App\Models\AnotherUser;
// or return $this->user('another_user') instanceof \App\Models\AnotherUser;
}
}
It gives me the following error:
Instanceof between App\Models\DefaultUser|null and App\Models\AnotherUser will always evaluate to false.
Hello 俊博! 👋 Thank you for your report.
Seems like we only have an extension for Illuminate\Contracts\Auth\Guard::user
.
Hey @szepeviktor thanks for your reply!
Unfortunately I'm not quite sure what you meant; since the method is specified to return mixed
by Laravel itself, I thought the problem comes from larastan, but is there any other factor that can cause this problem?
If so should I check if it happens on a fresh new setup?
Here we have something https://github.com/nunomaduro/larastan/blob/831f09bebfe10f1a9e1c3772476437511f1c6756/src/Concerns/LoadsAuthModel.php#L15-L17 It may cause your issue.
Hi,
Can you explain how $this->user()
would return AnotherUser
if default guard is configured to return DefaultUser
?
Hello @canvural ,
I have checked with fresh new laravel install, and I did confirmed auth()->user()
can return non-default one.
I set up a repository for you to easily see if it actually behaves like that:
https://github.com/mirucon/laravel_playground/blob/2bfae0ad22153fec62e0e9e0cf05af3508bc9319/config/auth.php
https://github.com/mirucon/laravel_playground/blob/2bfae0ad22153fec62e0e9e0cf05af3508bc9319/tests/Feature/ExampleTest.php
https://github.com/mirucon/laravel_playground/runs/6560100332
Just added a case for FormRequest
as well: https://github.com/mirucon/laravel_playground/commit/c75b6a723d0fe528fed36dc74818143364e01388
I can't tell you how it works because it's pretty hard to find out the internal behaviour of this; but at least from my experience, Laravel will try every possible guard one by one (which you can clearly see if you have a custom guard class) when no $guard
parameter is specified.
Hey @canvural, have you seen the example above? If you need anything else to fix the problem, please let me know so I can set it up for you.
I see. It changes in tests with actingAs
There is plan to implement this. It's a rare edge case.
@canvural I used actingAs
just for convenience. It definitely changes when not using it as well. I have quite many codes relying on this and they are working in production.
Any one got a way to fix this? I have a project with a few different guards/providers, each with their own user models... and somehow it is thinking it's always the first provider, regardless of the provided ->user('other-guard')
param passed in.
I still have to override the variable with the @var
comment.
It's quite sad the problem has been left unresolved just because of the maintainer's misunderstanding :(
@canvural Could you revisit this issue?
@fabriciojs what you're describing is fixed by #1782
@fabriciojs what you're describing is fixed by #1782
Great, looking forward to have that merged in & released. Thank you!
This issue was resolved by https://github.com/larastan/larastan/pull/1848, and released in 2.9.2