php 具有多种角色的 Laravel 中间件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43901719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 02:55:51  来源:igfitidea点击:

Laravel middleware with multiple roles

phplaravel-5.4laravel-bladelaravel-middleware

提问by Jesse

I've been running into some issues with Laravel's middleware. Let me tell you the basic idea of what I'm trying to accomplish:

我遇到了 Laravel 中间件的一些问题。让我告诉你我正在努力完成的基本思想:

Registered users on the site will have one of four roles:

网站上的注册用户将具有以下四种角色之一:

  1. Student (default): can access 'index' and 'show' views
  2. Approver: can access previous, plus 'overview', 'update'
  3. Editor: can access previous, plus 'create', 'edit' and 'store'
  4. Admin: can access everything
  1. 学生(默认):可以访问“索引”和“显示”视图
  2. 审批人:可以访问上一个,加上“概览”、“更新
  3. 编辑器:可以访问上一个,加上“创建”、“编辑”和“存储
  4. 管理员:可以访问所有内容

fyi: 'overview' is sort of an index view, but only for approver role and higher

仅供参考:“概览”是一种索引视图,但仅适用于审批者角色及更高级别

What would you guys suggest is the best way to go about doing this? This is what I've done so far, but it doesn't seem to work:

你们有什么建议是最好的方法去做这件事?这是我到目前为止所做的,但似乎不起作用:



Kernel.php

内核.php

protected $middlewareGroups = [
...
    'approver+' => [
        \App\Http\Middleware\Approver::class,
        \App\Http\Middleware\Editor::class,
        \App\Http\Middleware\Admin::class,
    ],
];

protected $routeMiddleware = [
...
    'student' => \App\Http\Middleware\Student::class,
    'approver' => \App\Http\Middleware\Approver::class,
    'editor' => \App\Http\Middleware\Editor::class,
    'admin' => \App\Http\Middleware\Admin::class,
];


Http\Middleware\Admin.php

Http\Middleware\Admin.php

public function handle($request, Closure $next)
{
   if (Auth::check())
   {

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

    return redirect('login');
}


The 'User' Eloquent model:

“用户”雄辩模型:

public function isAdmin()
{
    if($this->role_id === 4)
    { 
        return true; 
    } 
    else 
    { 
        return false; 
    }
}

I've done the exact same in the Approver and Editor middleware files, and in the isApprover and isEditor functions in the User model, only edited the checked value in the if-statement to 2 and 3 respectively.

我在 Approver 和 Editor 中间件文件中做了完全相同的事情,在 User 模型中的 isApprover 和 isEditor 函数中,只将 if 语句中的选中值分别编辑为 2 和 3。

Finally, here's what I've done in my routes\web file:

最后,这是我在 routes\web 文件中所做的:

Route::get('scholen', 'SchoolsController@index');
Route::get('admin/scholen/overzicht', 'SchoolsController@overview')->middleware('approver+');
Route::get('admin/scholen/maken', 'SchoolsController@create')->middleware('approver+');
Route::post('scholen', 'SchoolsController@store')->middleware('approver+');
Route::get('scholen/{id}', 'SchoolsController@show');
Route::get('admin/scholen/{id}/bewerken', 'SchoolsController@edit')->middleware('admin');
Route::patch('admin/scholen/{id}', 'SchoolsController@update')->middleware('admin');
Route::delete('admin/scholen/{id}', 'SchoolsController@destroy')->middleware('admin');

It isn't all exactly on point yet, but I got stuck since when I log in as a user with Approver rights and try to access the schools overview, it redirects me back to the home page.

这还不是完全正确,但我被卡住了,因为当我以具有批准者权限的用户身份登录并尝试访问学校概览时,它会将我重定向回主页。

In general, it just feels like I'm working much too chaotically and not right at all, could somebody give me advice on how to do it more efficiently?

总的来说,我只是觉得我的工作太混乱了,根本不正确,有人可以就如何更有效地工作给我建议吗?

Thank you very much in advance!

非常感谢您提前!

回答by jfadich

You should't have a separate middleware for each role. It will get very messy very fast. It would be better to have a single role checking middleware that can check against any role passed to it.

您不应该为每个角色设置单独的中间件。它会很快变得非常混乱。最好有一个单一的角色检查中间件,可以检查传递给它的任何角色。

Http\Kernel.php

Http\Kernel.php

protected $routeMiddleware = [
    ...
    'role' => \App\Http\Middleware\Role::class,
];

Http\Middleware\Role.php

Http\Middleware\Role.php

public function handle($request, Closure $next, ... $roles)
{
    if (!Auth::check()) // I included this check because you have it, but it really should be part of your 'auth' middleware, most likely added as part of a route group.
        return redirect('login');

    $user = Auth::user();

    if($user->isAdmin())
        return $next($request);

    foreach($roles as $role) {
        // Check if user has the role This check will depend on how your roles are set up
        if($user->hasRole($role))
            return $next($request);
    }

    return redirect('login');
}

Finally in your web routes

最后在你的网络路线中

Route::get('admin/scholen/overzicht', 'SchoolsController@overview')->middleware('role:editor,approver');
Route::get('admin/scholen/{id}/bewerken', 'SchoolsController@edit')->middleware('role:admin');