多个中间件在相同路由上具有许可

时间:2015-08-23 11:15:27

标签: php laravel routes laravel-5.1

我有多个中间件(studen,parent,admin)并使用该中间件创建一些路由组。但是如果用户在任何一个组中并且属于任何一个中间件而某些路由可以访问,但是如果在其他中间件例如教师中则不能访问。我在文档中使用类似的东西:http://laravel.com/docs/5.1/routing#route-groups但是当我放置一条路线时,当使用另一个中间件添加另一个路由组时,它不起作用。这可能吗?如何制作呢?

当我执行php artisan route时,它会给我一个错误

[Symfony\Component\Debug\Exception\FatalErrorException]
  Call to a member function inRole() on null

1 个答案:

答案 0 :(得分:2)

Laravel的路由中间件按照 routes.php 文件中的声明逐个执行。因此,如果其中一个通过抛出异常或返回一些resolise来拒绝访问,则下一个中间件将不会被执行。

为了实现这一目标,您需要一个能够检查当前用户是否具有任何所需角色的中间件。幸运的是,从 Laravel 5.1 开始,您可以将参数传递到 routes.php 文件中的中间件(请参阅http://laravel.com/docs/5.1/middleware#middleware-parameters),因此您只需要一个中间件类来处理所有情况。

示例中间件类可能如下所示:

class HasAnyRole
{
  public function handle($request, Closure $next, $roles)
  {
    // Return Not Authorized error, if user has not logged in
    if (!$request->user) {
      App::abort(401);
    }

    $roles = explode(',', $roles);
    foreach ($roles as $role) {
      // if user has given role, continue processing the request
      if ($request->user->hasRole($role)) {
        return $next($request);
      }
    }
    // user didn't have any of required roles, return Forbidden error
    App::abort(403);
  }  
}

Kernel.php

中注册中间件
protected $routeMiddleware = [
  'has_any_role' => 'App\Http\Middleware\HasAnyRole',
];

现在,在 routes.php 中,您可以将中间件应用于这样的组:

//this route is available only to users with role admin or author
Route::put('post/{id}', ['middleware' => 'has_any_role:admin,author', function ($id) {
    //
}]);

这应该可以解决问题,只需确保用户类具有 hasRole 方法。