Reputation: 1868
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:
roles_users
, but not relevant here)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
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
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
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