如何在Laravel 5中使用“OR”中间件进行路由?

17

我有两种用户类型,并创建了多个中间件。

有些路由需要允许两种用户类型。

我尝试使用以下代码:

Route::group(['namespace' => 'Common', 'middleware' => ['Auth1', 'Auth2']], function() {
    Route::get('viewdetail', array('as' => 'viewdetail', 'uses' => 'DashboardController@viewdetail'));
}); 

但它不起作用 :(


比起中间件,授权(门和策略)更适合。 - mercury
4个回答

21

中间件应该要么返回一个响应,要么将请求传递到管道中。中间件彼此独立,不应该知道其他中间件的运行情况。

您需要实现一个单独的中间件来允许2个角色,或者实现一个接受允许角色参数的单个中间件。

选项1:创建一个组合了Auth1和Auth2的中间件,可以检查2种用户类型。这是最简单的选项,虽然不太灵活。

选项2:由于版本5.1开始,中间件可以带参数 - 更多详情请参见:https://laravel.com/docs/5.1/middleware#middleware-parameters。您可以实现一个单个中间件,它将接受要检查的用户角色列表,并在路由文件中定义允许的角色。以下代码应该能解决问题:

// define allowed roles in your routes.php
Route::group(['namespace' => 'Common', 'middleware' => 'checkUserRoles:role1,role2', function() {
  //routes that should be allowed for users with role1 OR role2 go here
}); 

// PHP < 5.6
// create a parametrized middleware that takes allowed roles as parameters
public function handle($request, Closure $next) {

  // will contain ['role1', 'role2']
  $allowedRoles = array_slice(func_get_args(), 2);

  // do whatever role check logic you need
}

// PHP >= 5.6
// create a parametrized middleware that takes allowed roles as parameters
public function handle($request, Closure $next, ...$roles) {

  // $roles will contain ['role1', 'role2']

  // do whatever role check logic you need
}

5
这是一个例子如何在Laravel 5.2中使用OR条件将多个参数传递给中间件

而不是将多个参数添加到您的处理方法中,并且每次向应用程序添加新角色时都必须更新它,您可以使其动态。

中间件

 /**
 * Handle an incoming request.
 *
 * @param $request
 * @param Closure $next
 * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
 */
public function handle($request, Closure $next) {

    $roles = array_slice(func_get_args(), 2); // [default, admin, manager]

    foreach ($roles as $role) {

        try {

            Role::whereName($role)->firstOrFail(); // make sure we got a "real" role

            if (Auth::user()->hasRole($role)) {
                return $next($request);
            }

        } catch (ModelNotFoundException $exception) {

            dd('Could not find role ' . $role);

        }
    }

    Flash::warning('Access Denied', 'You are not authorized to view that content.'); // custom flash class

    return redirect('/');
}

路由

Route::group(['middleware' => ['role_check:default,admin,manager']], function() {
    Route::get('/user/{user_id}', array('uses' => 'UserController@showUserDashboard', 'as' => 'showUserDashboard'));
});

这将检查经过身份验证的用户是否具有至少一个提供的角色,如果是,则将请求传递给下一个中间件堆栈。当然,hasRole() 方法和角色本身需要由您实现。 您可以使用php 5.6
public function handle($request, Closure $next, ...$roles)
{
    foreach ($roles as $role) {

        try {
            if ($request->user()->can($role)) {
              return $next($request);
        }

        } catch (ModelNotFoundException $exception) {
          abort(403);
        }
    }

}

2
Route::group(['middleware' => 'role:manager,admin'], function () {}

在名为“role”的中间件中,您可以将参数解构成数组。
public function handle($request, Closure $next, ...$roles)
{
    $userRole = $request->user()->role;

    if (! $userRole || ! in_array($userRole->name, $roles)) {
        abort(403);
    }

    return $next($request);
}

0

简单来说,你可以使用这种语法,意思是如果有其中之一


 Route::group(['middleware' => ['role:first|second|third|....']], function () {});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接