Laravel-permission: using middleware with multiple guards

Created on 6 Sep 2017  路  10Comments  路  Source: spatie/laravel-permission

I am using multiple guards for admin - web_manager
How to add the web_manager guard into this code?

public function __construct() { $this->middleware(['role:super-admin']); }

Thank.

Most helpful comment

@halilcosdu,

After setting up another guard, I did something like this:

Route::group(['prefix' => 'whatever', 'middleware' => ['auth:member,admin' ,'role:super_admin|another_role']], function() {
...
});

All 10 comments

You could replace the RoleMiddleware and accept a $guard parameter, and test using auth()->user()->hasRole(Role::findByName($role, $guard))

Or you could use permissions instead of roles ... and then you could replace the PermissionMiddleware with something that accepts another parameter $guard and then tests with auth()->user()->hasPermissionTo($role, $guard)

@drbyte Happy New Year!
You mean to replace RoleMiddleware or PermissionMiddleware to auth()->user()->*($role,$guard) in middleware ?
I don't understand your answer. Could you give a more detailed one ?
Thanks

Deferring to @AlexVanderbist for comment.

Hello,
I followed your advice @drbyte
I have two guards (web and api)
I modified the file PermissionMiddleware.php like this:

 <?php

 namespace Spatie\Permission\Middlewares;

 use Closure;
 use Illuminate\Support\Facades\Auth;
 use Spatie\Permission\Exceptions\UnauthorizedException;

 class PermissionMiddleware
 {
     public function handle($request, Closure $next, $permission, $guard)
     {
         if (app('auth')->guest()) {
             throw UnauthorizedException::notLoggedIn();
         }

         $permissions = is_array($permission)
             ? $permission
             : explode('|', $permission);
         foreach ($permissions as $permission) {
             if (app('auth')->user()->hasPermissionTo($permission, $guard)) {
                 return $next($request);
             }
             /* 
             if (app('auth')->user()->can($permission)) {
                 return $next($request);
             }*/
         }

         throw UnauthorizedException::forPermissions($permissions);
     }
 }

and RoleMiddleware.php similarly.

Then from routes I can call the laravel-permission like this:
routes from api.php:

Route::middleware('auth:api', 'permission:get from api,api')->get('/test', function (Request $request) {
    return json_encode ("Welcome to REST API, ".Auth::user()->username);
});

routes from web.php

Route::get('/', function () {
    return view('/homepage');
})->name('homepage')->middleware('permission:access homepage,web');

Everything is working great and as expected. My question: is this correct approach? (e.g. am I not slowing down the app?). And silly question, why isn't this already in laravel-permission? How else could I differentiate different permissions for different guards from middleware?

Thanks a lot

I have a PR that needs testing: https://github.com/spatie/laravel-permission/pull/704 It adds the ability to pass a $guard parameter to can(), similar to what you're after.

Are you able to try it out? and in your middleware go back to using can() but pass $guard as an optional parameter.

Route::middleware('permission:SYSTEM_MANAGEMENT,api')->group(function () { Route::resource('permissions', 'PermissionController'); });

Guys I have multiple guards, any idea why it's not working.

@halilcosdu wrote:

Route::middleware('permission:SYSTEM_MANAGEMENT,api')->group(function () { Route::resource('permissions', 'PermissionController'); });

Guys I have multiple guards, any idea why it's not working.

The middleware currently provided in this package doesn't check for a specific guard. You could modify it similar to how @elerocks did above if you wanted to use your own custom middleware for it.

@halilcosdu,

After setting up another guard, I did something like this:

Route::group(['prefix' => 'whatever', 'middleware' => ['auth:member,admin' ,'role:super_admin|another_role']], function() {
...
});

@ediblemanager thanks for your comment. Works perfectly :)

put this in begin __construct : $this->middleware('auth:gardName');

hossam_elbrens

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hosseinnedaei picture hosseinnedaei  路  3Comments

enghelewa picture enghelewa  路  4Comments

Dreambox13 picture Dreambox13  路  3Comments

feliperoan picture feliperoan  路  3Comments

neoreids picture neoreids  路  3Comments