v2 guard lookup currently looks to the model's guard_name property, with fallbacks down to finally the first available guard in your config array of guards (not the one listed as "default"). Null doesn't disable this lookup.
So, wherever you don't specify a guard when doing a permission check, it does the lookup according to that pattern I just described.
Shouldn't it check the guard of logged in user?
like this
function activeGuard()
{
foreach (array_keys(config('auth.guards')) as $guard) {
if (auth()->guard($guard)->check()) return $guard;
}
return null;
}
How can I check based on the guard of user?
_Originally posted by @Daniyal-Javani in https://github.com/spatie/laravel-permission/issues/892#issuecomment-569771727_
@Daniyal-Javani I'd like to see a future version of this package honor the guard that the user has been assigned during their login/authentication.
A PR which updates that functionality would be welcome. Ideally with tests.
@drbyte
That already is the case unless I'm wrong.
https://github.com/spatie/laravel-permission/blob/master/src/Guard.php#L47
Source: https://github.com/laravel/framework/issues/22096
https://github.com/laravel/framework/blob/3c397ea1f4c7af4346f4f83144ea8d3ff307f405/src/Illuminate/Auth/Middleware/Authenticate.php#L63
@musapinar Yes, but the next line overrides it with the model's guard, which leaves many people confused about why the package checks against a different guard than the one the user is using (they would say "it checks against the wrong guard").
(See several issues about guards: most are complaining of this factor.)
It's a complex change to make, because it's messing with a matrix of values created by conflating authorization with authentication. I'd rather remove all mention of guards altogether, and let the application implement guard-related rules.
But there's a large user base depending on the guard features of this package, even though they wish it worked in a way that honoured the user's logged-in-guard with more prominence and more consistency.
@musapinar I think the first starting point though is reviewing where it's not working as desired, writing the tests for that, and then getting those tests to pass.
OK, what about this test
https://github.com/Daniyal-Javani/laravel-permission/commit/54dde601de025813c84926a0be151c421be84b31
The test will fail (server error) because there is no permission named do_that with web gaurd while its guard is api and the user had logged in with api gaurd.
@Daniyal-Javani @drbyte
Test looks good to me.
I'm afraid I can't/won't help much on this one as I do not make use of that guard feature at all. I enforce web no matter what since I do not want to duplicate roles/permissions for each guard. (Here is my glorious fix btw : https://i.imgur.com/OO3xe3w.png)
Not sure how elegant the following is, but it passes all tests green :
->keys()
->filter(function ($guard) {
return request()->user() ? auth()->guard($guard)->check() : true;
});
https://github.com/spatie/laravel-permission/blob/master/src/Guard.php#L42
https://i.imgur.com/6dlJmza.png
Good luck.
Hi, when you release this patch? Thank's
If you are looking for a solution that works without this feature:
You can set up a second user Model, such as App\User and AppApiUser.
Then make sure to use the ApiUser in your auth.php for your api guard.
class ApiUser extends Authenticatable {
use HasRoles;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'users';
/**
* The guard that this user should be authenticated with.
*/
protected $guard_name = 'api';
}
class User extends Authenticatable {
use HasRoles;
}
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'apiusers',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'apiusers' => [
'driver' => 'eloquent',
'model' => App\Models\ApiUser::class,
],
],
I was able to get it working like this, maybe someone will find this helpful.
Most helpful comment
@Daniyal-Javani @drbyte
Test looks good to me.
I'm afraid I can't/won't help much on this one as I do not make use of that guard feature at all. I enforce
webno matter what since I do not want to duplicate roles/permissions for each guard. (Here is my glorious fix btw : https://i.imgur.com/OO3xe3w.png)Not sure how elegant the following is, but it passes all tests green :
https://github.com/spatie/laravel-permission/blob/master/src/Guard.php#L42
https://i.imgur.com/6dlJmza.png
Good luck.