具有多种角色的Laravel中间件

时间:2017-05-10 19:59:25

标签: php laravel-5.4 laravel-blade laravel-middleware

我一直在使用Laravel的中间件遇到一些问题。 让我告诉你我想要完成的基本想法:

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

  1. 学生(默认):可以访问' 索引'和' 显示'视图
  2. 审批人:可以访问之前的,<+> 概述&#39; 更新&#39;
  3. 编辑:可以访问上一个,再加上创建&#39; <#39; 编辑&#39;和&#39; 商店&#39;
  4. 管理员:可以访问所有内容
  5. fyi:&#39;概述&#39;是一种索引视图,但仅适用于审批者角色和更高级别

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

    Kernel.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 \中间件\ admin.php的

    public function handle($request, Closure $next)
    {
       if (Auth::check())
       {
    
            if(Auth::user()->isAdmin())
            {
                return $next($request);
            }
       }
    
        return redirect('login');
    }
    

    &#39;用户&#39;雄辩的模特:

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

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

    最后,这是我在我的路线\网络文件中所做的事情:

    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');
    

    目前还不完全正确,但是当我以具有审批者权限的用户身份登录并尝试访问学校概述时,我陷入困境,它将我重定向回主页。

    总的来说,只是感觉我的工作过于混乱而且根本不对,有人可以就如何更有效地提供建议吗?

    非常感谢你!

3 个答案:

答案 0 :(得分:17)

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

HTTP \ Kernel.php

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

HTTP \中间件\ 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');
}

最后在你的网络路线

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

答案 1 :(得分:4)

这是对 fafich 回应的补充。

在 IF 中使用 in_array 而不是使用 FOREACH,如下所示:

if (! in_array ($ user-> hasRole ($ role), $ roles) {

 // returns if you dont have permission
}

return $ next ($ request);

答案 2 :(得分:0)

为每个Login Session请求完成Handle函数

public function handle($request, Closure $next)
{
    if (! Auth::check()) {
        return redirect()->route('login');
    }

    if (Auth::user()->role == 1) {
        return redirect()->route('superadmin');
    }

    if (Auth::user()->role == 5) {
        return redirect()->route('academy');
    }

    if (Auth::user()->role == 6) {
        return redirect()->route('scout');
    }

    if (Auth::user()->role == 4) {
        return redirect()->route('team');
    }

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

    if (Auth::user()->role == 2) {
        return redirect()->route('admin');
    }
}