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

Posted

技术标签:

【中文标题】将数组传递给laravel中的中间件【英文标题】:Pass an array to a middleware in laravel 【发布时间】:2017-09-26 21:23:39 【问题描述】:

我在一个名为 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()

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

【问题讨论】:

【参考方案1】:

您可以使用middleware 中的explode 函数将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');

【讨论】:

【参考方案2】:

将参数作为字符串发送

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

【讨论】:

【参考方案3】:

路线:

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:注册路由中间件

// 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);

【讨论】:

【参考方案4】:

我不完全理解你的函数是做什么的,但你可以试试这样的:

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

【讨论】:

【参考方案5】:

在 laravel 中,您可以使用逗号 , 分隔要传递给中间件的参数,如下所示:

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

请注意,这不会将参数作为数组发送,因此您不能循环 $roles,除非您将传递的参数用作 ellipsis parameters,如下所示:

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

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

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

【讨论】:

我只需要那个省略号参数。 $roles 变成数组。非常感谢。

以上是关于将数组传递给laravel中的中间件的主要内容,如果未能解决你的问题,请参考以下文章

如何将中间件分配给 Laravel 中的路由(更好的方法)? [关闭]

关于laravel5.5路由的一些问题,持续更新

Laravel 中间件将变量返回给控制器

Laravel - 将变量从中间件传递到控制器/路由

将 Laravel 路由中的数组传递给 Blade 模板

如何将字符串或数组发送到 laravel 中间件