daugaard47
daugaard47

Reputation: 1868

How to add multiple roles to a route group laravel

I'm trying to add multiple roles to a route group in my web file in Laravel. I would like protect certain routes based on the users Role like the admin section.

Some Routes need multiple roles for access.

Example Roles:

This works and I can go to the admin panel if loged in and have One Role only in the route group.

Route::middleware(['auth','role:SuperAdmin'])->group(function () {
Secret routes..
});

This does not work if I try and add more roles to to the route group like this: Route::middleware(['auth','role:SuperAdmin|Admin|Moderator'])->group(function () {

Note the 'role:SuperAdmin|Admin|Moderator'


This is the RoleMiddleware file:

    public function handle($request, Closure $next, $role, $permission = null)
    {
        if (!$request->user()->hasRole($role)) {
            abort(404);
        }

        if ($permission !== null && !$request->user()->can($permission)) {
            abort(404);
        }

        return $next($request);
    }

The User Class has a trait called use:HasPermissionTrait

class User extends Authenticatable
{
    use Notifiable, HasPermissionsTrait, Billable;

In that HasPermissionsTrait I have the following: I have permission setup fine, just focusing on the Roles in this file. I moved the Role logic to the top.

use App\{Role, Permission};

trait HasPermissionsTrait
{
    public function hasRole(...$roles)
    {
        foreach ($roles as $role) {
            if ($this->roles->contains('name', $role)) {
                return true;
            }
        }

        return false;
    }

    public function roles()
    {
        return $this->belongsToMany(Role::class, 'users_roles');
    }
    
    ... // Permission logic start here...
}

Worth Mentioning: The tables for roles are:

Just need to know how to get this working in the route group: 'role:SuperAdmin|Admin|Moderator'


Solution: RoleMiddleware file:

    public function handle($request, Closure $next, $role, $permission = null)
    {
        $role = strtolower( $request->user()->hasRole($role));
        $allowed_roles = array_slice(func_get_args(), 2);
        
        if (!$request->user()->hasRole(in_array($role, $allowed_roles))) {
            abort(404);
        }

        if ($permission !== null && !$request->user()->can($permission)) {
            abort(404);
        }

        return $next($request);
    }

Can do route group like this. Route::middleware(['auth','role:SuperAdmin|Admin'])->group(function () {

Upvotes: 1

Views: 8535

Answers (3)

Leyiang
Leyiang

Reputation: 582

This is what I did in my CheckRole Middleware

public function handle($request, Closure $next) {
    // I'm using the api guard
    $role = strtolower( request()->user()->type );
    $allowed_roles = array_slice(func_get_args(), 2);

    if( in_array($role, $allowed_roles) ) {
        return $next($request);
    }

    throw new AuthenticationException();
}

And in my router file

Route::group(["middleware" => "role:admin,worker"], function() {

});

This might not be the perfect solution, at least it works for me.

Upvotes: 2

linktoahref
linktoahref

Reputation: 7972

explode the roles in your middleware and check against the available roles

public function handle($request, Closure $next, $role, $permission = null)
{
    $roles = is_array($role)
        ? $role
        : explode('|', $role);

    if (!$request->user()->hasRole($roles)) {
        abort(404);
    }

    if ($permission !== null && !$request->user()->can($permission)) {
        abort(404);
    }

    return $next($request);
}

Upvotes: 0

bhumin
bhumin

Reputation: 196

    Route::middleware(['auth'])->group(function () {
      //Routes available to super admin
      Route::middleware(['role:SuperAdmin'])->group(function () {
        //write route hear 
      });
        
      //Routes available to SuperAdmin, Admin and Moderator
      Route::middleware(['role:SuperAdmin|Admin|Moderator'])->group(function () {
        //write route hear 
      })
  });

try this way to define route group of routing. I already use this syntax and it's work.
define auth in parent middleware group and roles defined in the child middleware groupe.

Upvotes: 1

Related Questions