Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel: How to use Gates with multiple Guards

I have a traditional web application that has a number of different user types, and each user type has its own Authentication guard.

'guards' => [

    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'admin' => [
        'driver' => 'session',
        'provider' => 'admin',
    ],
    'timekeeper' => [
        'driver' => 'session',
        'provider' => 'timekeeper',
    ],
    'api' => [
        'driver' => 'token',
        'provider' => 'users',
    ],
],

Most my users authenticate using the 'web' guard, however administrators and timekeepers each use their own guard, which is attached to an appropriate user provider.

This is fine until I try to use authentication gates. If I authenticate a user against the system's default guard (e.g. 'web'), then the gates work as expected. If I authenticate against any other guard however, then all Gate::allows(...) calls are DENIED.

Even the following ability is denied:

Gate::define('read', function ($user) {
    return true;
});

Presumably this is due to line 284-286 in Illuminate\Auth\Access\Gate:

if (! $user = $this->resolveUser()) {
    return false;
}

As far as I can see, my options are to:

  • Go back to using a single 'web' guard, with a user provider that can locate any type of user (but I'm not sure how that would work if I start using an API in parallel)
  • Somehow set the default guard at run time, depending on the type of the current user. (It is currently set in the config file)
  • Somehow inject a different user resolver in to the Gate facade (again, depending on the type of the current user)

None of these seems intuitive however. Am I missing something?

like image 967
DatsunBing Avatar asked Oct 19 '25 21:10

DatsunBing


1 Answers

It's not the most elegant solution because it requires a lot of extra boilerplate code, but you can use Gate::forUser($user)->allows() instead of just Gate::allows() where $user comes from Auth::guard().

like image 86
Moshe Katz Avatar answered Oct 22 '25 14:10

Moshe Katz