Reputation: 129
I got this handle in a middleware called rolMiddleware:
public function handle($request, Closure $next, $roles)
{
//dd($request->user());
foreach ($roles as $rol) {
if ($request->user()->getTipoUsuario($request->user()->tipo_usuario_id)->getNombreTipoUsuario() == $rol) {
return $next($request);
}
}
abort(403, "¡No hay autorizacion!");
}
But $roles is an array, here is the route where I use the middleware:
Route::get('/mid', ['middleware' => 'roles:super admin', function () {
return "done";
}]);
and the error that gives me is:
ErrorException in RolMiddleware.php line 22:
Invalid argument supplied for foreach()
You may thing that I do not need an array because I am only using it in super admin, for that route I only need super admin, but there would be routes that can be for super admin and the admin of an area.
Upvotes: 8
Views: 17339
Reputation: 1
You should always have return $next($request);
at the end of a middleware file... Some of these examples fail to do that.
Here's how your routes will be (web.php file):
Route::middleware('auth')->group(function () {
Route::middleware('CheckRole:super-admin')->group(function () {
//super-admin only routes here
});
Route::middleware('CheckRole:user')->group(function () {
//user only routes here
});
});
To add more roles to the above code, just put CheckRole:super-admin,user
you can keep going with commas for the specific group.
The middlewares below will automatically keep anyone without permission out of the areas specified above, and only when a user is logged in
Make sure to add the below middleware to:
App\Http\Kernel.php
Under
protected $middlewareAliases = [
Put the following line:
'CheckRole' => \App\Http\Middleware\CheckRole::class,
Your middleware will be:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class CheckRole
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
*/
public function handle(Request $request, Closure $next, ...$roles): Response
{
if ($request->user()) {
$userRole = Auth::user()->role->value('name');
if (! in_array($userRole, $roles)) {
abort(403, 'Your account permissions do not allow access to the requested page');
}
}
return $next($request);
}
}
This assumes you only have 1 role for 1 user. If you have multiple roles for 1 user, that would be a different check in your middleware code
If you have multiple Roles for multiple Users, you can use this middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class CheckRole
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
*/
public function handle(Request $request, Closure $next, ...$roles): Response
{
if ($request->user()) {
$userRoles = Auth::user()->roles
->pluck('name')
->toArray();
if (! array_intersect($userRoles, $roles)) {
abort(403, 'Your account permissions do not allow access to the requested page');
}
}
return $next($request);
}
}
Upvotes: 0
Reputation: 2092
You can use explode
function within middleware
for converting string
to array
.
Controller:
public function __construct()
{
$this->middleware('RoleCheck:admin|user')->except(['index', 'show']);
}
Middleware:
public function handle(Request $request, Closure $next, $roles)
{
$user = Auth::user();
$roles = explode("|", $roles); // convert $roles to array
foreach ($roles as $role) {
if ($user->hasRole($role))
return $next($request);
}
return redirect('login');
}
Upvotes: 1
Reputation: 41
Send parameter as string like as
Route::prefix('panel')->middleware('auth:admin|editor')->group(function (){
Route::get('/', [SiteController::class, 'index'])->name('site.index');
}
Program in middleware to sense this string as array
if (in_array(Auth::user()->rule, explode('|', $access))) {
return $next($request);
} else {
return redirect()->route('site.denied');
}
Upvotes: 3
Reputation: 820
Route:
Route::get('/access', ['middleware' => 'hasroles:super,admin', function () {
}]);
passing one parameter to check user have created permission in my cause
Route::middleware('admin')->namespace('Admin')->prefix('admin')->group(function(){
Route::get('/home', 'MainController@getIndex')->name('admin.index')->middleware("hasrole:create");
Middleware:
1.Using Parameters
public function handle($request, Closure $next, $parm1, $parm2){}
2.Using var-arg
public function handle($request, Closure $next, $parm1, $parm2){}
public function handle($request, Closure $next, ...$parm1){}
Two-way Middleware Use
1: Register routeMiddleware
// Within App\Http\Kernel Class...
protected $routeMiddleware = [
'hasrole' => \Illuminate\Auth\Middleware\HasRole::class,
Using:
Route::get('admin/profile', function () {
})->middleware('hasrole');
2: Not Register in routeMiddleware
Using:
use App\Http\Middleware\HasRole;
Route::get('admin/profile', function () {
//
})->middleware(HasRole::class);
Upvotes: 4
Reputation: 2182
I don't exactly understand what your functions do, but you can try something like this:
public function handle($request, Closure $next, $roles)
{
if(is_array($roles)){
//dd($request->user());
foreach ($roles as $rol) {
if ($request->user()->getTipoUsuario($request->user()->tipo_usuario_id)->getNombreTipoUsuario() == $rol) {
return $next($request);
}
}
}else{
if($request->user()->getTipoUsuario($request->user()->tipo_usuario_id)->getNombreTipoUsuario() == $roles)
return $next($request);
}
abort(403, "¡No hay autorizacion!");
}
Upvotes: 0
Reputation: 8288
In laravel , you can separate your parameters which you want to pass to middleware using comma ,
as follows:
Route::get('/mid', ['middleware' => 'roles:super,admin', function () {
// ^ note this
return "done";
}]);
note that, this won't send parameters as an array, so you can't loop over $roles
unless you use your passed parameters as ellipsis parameters as follows :
public function handle($request, Closure $next, ...$roles)
rather, you will need to use a single parameter for each role:
public function handle($request, Closure $next, $role1, $role2) // .... and so on
Upvotes: 28