如何使用Laravel 5.2中的OR条件将多个参数传递给中间件

如何使用Laravel 5.2中的OR条件将多个参数传递给中间件,laravel,laravel-5.2,Laravel,Laravel 5.2,我正试图设置权限,以访问两个不同的用户角色Admin,Normal\u user的操作,如下所示 Route::group(['middleware' => ['role_check:Normal_User','role_check:Admin']], function() { Route::get('/user/{user_id}', array('uses' => 'UserController@showUserDashboard', 'as' => 'sh

我正试图设置权限,以访问两个不同的用户角色Admin,Normal\u user的操作,如下所示

Route::group(['middleware' => ['role_check:Normal_User','role_check:Admin']], function() {
        Route::get('/user/{user_id}', array('uses' => 'UserController@showUserDashboard', 'as' => 'showUserDashboard'));
    });
管理员或普通用户均可访问此路由。但在这个中间件配置中,用户必须是管理员和普通用户。如何在中间件参数传递中添加或条件?或者是否有其他方法给予许可

下面是我的中间件

public function handle($request, Closure $next, $role)
    {
        if ($role != Auth::user()->user_role->role ) {
            if ($request->ajax() || $request->wantsJson()) {
                return response('Unauthorized.', 401);
            } else {
                return response('Unauthorized.', 401);
            }
        }
        return $next($request);
    }
<?php

 namespace Tests\Feature;

 use App\User;
 use Illuminate\Foundation\Testing\RefreshDatabase;
 use Tests\TestCase;
 use function factory;

 class MustBeOFUserTypeTest extends TestCase
 {
    use RefreshDatabase;

    /** @test * */
    public function it_accepts_the_admin()
    {
       $this->signIn(factory(User::class)->states('administrator')->create());

       $this->get('/usertype')->assertStatus(200);
     }

     /** @test * */
     public function it_rejects_normal_users()
     {
       $this->signIn();

       $this->get('/usertype')->assertStatus(423);
      }

      /** @test **/
      public function it_accepts_authors()
      {

        $this->signIn(factory(User::class)->states('author')->create());

        $this->get('/usertype')->assertStatus(200);
       }

       public function signIn($user = null)
       {

            $u = $user ?: factory('App\User')->states('normal')->create();

             $this->be($u);

             return $this;
            }
       } 

有人可以回复吗?

要添加多个参数,需要用逗号分隔:

Route::group(['middleware' => ['role_check:Normal_User,Admin']], function() {
        Route::get('/user/{user_id}', array('uses' => 'UserController@showUserDashboard', 'as' => 'showUserDashboard'));
    });
然后您可以在中间件中访问它们,如下所示:

public function handle($request, Closure $next, $role1, $role2) {..}

这里的逻辑是由你来实现的,没有自动的方式说“或”

不必在handle方法中添加多个参数,也不必在每次向应用程序添加新角色时对其进行更新,您可以使其成为动态的

中间件

 /**
 * 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'));
});
路线

 /**
 * 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

 namespace App\Http\Middleware;

 use Closure;
 use function abort;
 use function array_flip;
 use function array_key_exists;
 use function array_slice;
 use function func_get_args;

 class MustBeOFUserType
 {
     /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
     public function handle($request, Closure $next)
     {
        $roles = array_slice(func_get_args(), 2);  // ['admin', 'author']

        //flip $roles to get ['admin' => 0, 'author' => 1];
        if (!auth()->guest() && array_key_exists(auth()->user()->role->name, array_flip($roles))) {

          return $next($request);
        }
        abort(423, 'Sorry you are not authrized !');

     }
   }
记住上的空格:admin,author“like”:admin,author“将导致错误

为了进行合理性检查,如果您是像我这样的TDD人员,请使用此测试中间件

public function handle($request, Closure $next, $role)
    {
        if ($role != Auth::user()->user_role->role ) {
            if ($request->ajax() || $request->wantsJson()) {
                return response('Unauthorized.', 401);
            } else {
                return response('Unauthorized.', 401);
            }
        }
        return $next($request);
    }
<?php

 namespace Tests\Feature;

 use App\User;
 use Illuminate\Foundation\Testing\RefreshDatabase;
 use Tests\TestCase;
 use function factory;

 class MustBeOFUserTypeTest extends TestCase
 {
    use RefreshDatabase;

    /** @test * */
    public function it_accepts_the_admin()
    {
       $this->signIn(factory(User::class)->states('administrator')->create());

       $this->get('/usertype')->assertStatus(200);
     }

     /** @test * */
     public function it_rejects_normal_users()
     {
       $this->signIn();

       $this->get('/usertype')->assertStatus(423);
      }

      /** @test **/
      public function it_accepts_authors()
      {

        $this->signIn(factory(User::class)->states('author')->create());

        $this->get('/usertype')->assertStatus(200);
       }

       public function signIn($user = null)
       {

            $u = $user ?: factory('App\User')->states('normal')->create();

             $this->be($u);

             return $this;
            }
       } 
您可以在PHP5.6中使用3点(…)语法+

中间件的句柄功能


在您的middlewear文件checkRole.php中,这个超级简单的动态实现可能会对某些人很方便:

public function handle($request, Closure $next, ... $roles)
{
    $found = false;
    foreach ($roles as $role) {
        if (session('type') == $role) {
            $found = true; break;
        }
    }

    if (!$found) {
        return back()->with('error','Access denied!');
    }

    return $next($request);
}
并从web.php调用middlewear,输入需要传递的参数:

Route::get('/approve',  'aController@approve')  ->middleware('roles:admin');
Route::get('/dashboard','bController@dashboard')->middleware('roles:admin,user');
另外,不要忘记在Kernel.php中修改middlewear密钥名:

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

美好的令人惊讶的是,Laravel文档没有涵盖您希望将未知数量的参数传递给中间件的情况。它被称为“splat操作符”