将多个中间件添加到 Laravel 项目

Add Multiple Middleware to Laravel Project

我是新手 laravel 我已经为我的每个角色创建了中间件,但是当我将它添加到我的路由时它不起作用。

如果我将单个中间件添加到我的路由中,它可以正常工作,但是当我添加第二个和第三个中间件时,它将无法工作。

它不会显示授权的路线 user 它会将其重定向到家,

我的用户模型:

public function IsAdmin()
{
    if($this->role_id =='1')
    {
        return true;
    }
    else
    {
        return false;
    }
}

public function IsManager()
{
    if($this->role_id =='2')
    {
        return true;
    }
    else
    {
        return false;
    }
}

public function IsUser()
{
    if($this->role_id =='3')
    {
        return true;
    }
    else
    {
        return false;
    }
}

我的内核:

'IsAdmin' => \App\Http\Middleware\IsAdmin::class,
'IsManager' => \App\Http\Middleware\IsManager::class,
'IsUser' => \App\Http\Middleware\IsUser::class,

我的 IsAdmin 中间件:

public function handle($request, Closure $next)
{
    $user =Auth::User();
    if(!$user->IsAdmin())
    {
        return redirect('stock');
    }
    return $next($request);
}

我的 IsManager

public function handle($request, Closure $next)
{
    $user =Auth::User();
    if(!$user->IsManager())
    {
        return redirect('stock');
    }
    return $next($request);
}

和 IsUser

public function handle($request, Closure $next)
{
    $user =Auth::User();
    if(!$user->IsUser())
    {
        return redirect('stock');
    }
    return $next($request);
}

最后是我的路线

Route::get('approv',['middleware'=>['IsManager','IsAdmin'],function(){
    return view('approv');
}]);

这不会像您预期的那样工作。 所有 中间件需要通过才能处理请求,这意味着您的用户将需要同时是经理和管理员,根据您的设置这是不可能的。

您可以通过制作不同类型的中间件来解决这个问题:

内核:

'roles' => \App\Http\Middleware\Roles::class,

和角色中间件:

class Roles {

    private function checkRole($role) {
          switch ($role) {
              case 'user': return \Auth::user()->IsUser();
              case 'manager': return \Auth::user()->IsManager();
              case 'admin': return \Auth::user()->IsAdmin();
          }
          return false;
    }

    public function handle($request, Closure $next, ...$roles) 
    {
         foreach ($roles as $role) {
             if ($this->checkRole($role)) {
                 //At least one role passes
                 return $next($request);
             }
         } 
         //All checks failed so user does not have any of the required roles
         return redirect('stock');  
    }
}

然后要使用它,您只需执行以下操作:

Route::get('approv',['middleware'=>['roles:manager,admin'],function(){
   return view('approv');
}]);

这是可行的,因为 Laravel 中间件支持参数。您可以在声明中间件的位置将参数作为逗号分隔的字符串列表传递。在这种情况下,这是按 roles:manager,admin

完成的

Laravel 然后会将这些参数作为附加参数发送到 handle 方法中。这些可以使用可变参数的 PHPs 语法来访问。在这种特殊情况下,它是通过使用数组展开运算符。这在 PHP 手册的 function arguments 部分作为示例记录。

请注意,这实际上等同于说:

  public function handle($request, Closure $next, $role1=null, $role2=null, $role3=null)

但是使用展开运算符要方便得多,因为 ...$roles 是一个只包含在中间件中传递的角色的数组。