将数组传递给 Laravel 中的中间件

问题描述 投票:0回答:6

我在一个名为 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!");
}

但是 $roles 是一个数组,这是我使用中间件的路线:

Route::get('/mid', ['middleware' => 'roles:super admin', function () {
    return "done";
}]);

给我的错误是:

ErrorException in RolMiddleware.php line 22:
Invalid argument supplied for foreach()

您可能会认为我不需要数组,因为我只在超级管理员中使用它,对于该路线我只需要超级管理员,但会有可以用于超级管理员和区域管理员的路线。

php laravel authentication middleware
6个回答
27
投票

在 laravel 中,您可以使用逗号

,
分隔要传递给中间件的参数,如下所示:

Route::get('/mid', ['middleware' => 'roles:super,admin', function () {
//                                              ^ note this
    return "done";
}]);

请注意,这不会将参数作为数组发送,因此您无法循环

$roles
,除非您将传递的参数用作省略号参数,如下所示:

public function handle($request, Closure $next, ...$roles)

相反,您需要为每个角色使用一个参数:

public function handle($request, Closure $next, $role1, $role2) // .... and so on

4
投票

路线:

Route::get('/access', ['middleware' => 'hasroles:super,admin', function () {
}]);

传递一个参数来检查用户是否在我的中创建了权限 原因

Route::middleware('admin')->namespace('Admin')->prefix('admin')->group(function(){
    Route::get('/home', 'MainController@getIndex')->name('admin.index')->middleware("hasrole:create");

中间件:

1.使用参数

public function handle($request, Closure $next, $parm1, $parm2){}

2.使用var-arg

public function handle($request, Closure $next, $parm1, $parm2){}
public function handle($request, Closure $next, ...$parm1){}

双向中间件使用

1:注册routeMiddleware

// Within App\Http\Kernel Class...
protected $routeMiddleware = [
    'hasrole' => \Illuminate\Auth\Middleware\HasRole::class,

使用:

Route::get('admin/profile', function () {
})->middleware('hasrole'); 

2:未在routeMiddleware中注册

使用:

use App\Http\Middleware\HasRole;

Route::get('admin/profile', function () {
    //
})->middleware(HasRole::class);

3
投票

以字符串形式发送参数,如 as

Route::prefix('panel')->middleware('auth:admin|editor')->group(function (){
    Route::get('/', [SiteController::class, 'index'])->name('site.index');
}

在中间件中编程以将此字符串感知为数组

if (in_array(Auth::user()->rule, explode('|', $access))) {
   return $next($request);
} else {
   return redirect()->route('site.denied');
}

0
投票

我不太明白你的功能是做什么的,但你可以尝试这样的事情:

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!");
}

0
投票

您可以使用

explode
中的
middleware
函数将
string
转换为
array

控制器

public function __construct()
{
    $this->middleware('RoleCheck:admin|user')->except(['index', 'show']);
}

中间件

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');
}

0
投票

中间件文件末尾应该始终有

return $next($request);
...其中一些示例未能做到这一点。

您的路线如下(web.php 文件):

Route::middleware('CheckRole:super-admin')->group(function () {
//routes here
});

您的中间件将是:

<?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);
    }
}

这假设您只有 1 个用户的 1 个角色。如果您为 1 个用户拥有多个角色,那么您的中间件代码中将进行不同的检查

© www.soinside.com 2019 - 2024. All rights reserved.