一、RBAC分析

  基于角色的权限访问控制(Role- d Access Control),这里存在这么几个玩意儿:角色、权限,用户

  表:roles、permissions、role_has_permissions、model_has_roles、model_has_permissions(最后两张表可以看4.1有解释)

  明确:用户属于什么角色,那么角色拥有什么权限,用户自然拥有

  然后配置,就戳这里(后面就不添加了)~

二、角色的增删改查

  这个就很普通的功能了,略???

  但是有一些需要注意的地方:

    1. 更新操作时,method使用PUT

    2. Laravel的唯一性验证举例:\' \' => \'required|unique:roles, ,\'.$id,

      解释:对 字段进行验证——必填|唯一性验证:从拿一张表进行验证,验证什么字段,不验证当前字段(意思就是:比如你要修改的信息叫张三,表里面只有你当前编辑的这条记录是张三,所以忽略要这条记录,不然不就不唯一了嘛~)

    3.Laravel再进行更新、删除操作时,需要进行传参(也就是你要删除那一条记录的唯一标识),而要想获取这个参数可以使用:$this->route(\'XXX\')

三、权限(很重要,自学的过程中卡了好久)

  控制权限的方式有很多种,但我个人认为,(也是组长要求哈哈哈哈)最合适的方式是中间件

  1. 路由定义

1 // 权限管理
2 Route::get(\'role/permission/{role}\', \'RoleController@permission\');//页面显示
3 Route::post(\'role/permission/{role}\', \'RoleController@permissionStore\');//提交表单

  2. 页面展示

  无论通过Modals还是页面来显示权限页面都可以,我觉得少的话使用Modals(注意使用Modals的话,就不用show方法了),多的话页面展示

  然后就是遍历权限,有两种方法

  方法一:遍历permission.php文件

  方法二:通过方法来获取

1 public function permission(Role $role)
2 {
3     // 根据guard来获取权限
4     $modules = \\HDModule::getPermissionByGuard(\'admin\');
5 
6     // 分配  
7     // 之所以分配role是因为1.要进行checkbox选中判断,也就是判断当前用户是否有某权限  2.提交表单role_id
8     return view(\'admin::role.permission\', compact(\'role\'), compact(\'modules\'));
9 }

      然后就可以进行页面渲染了,@foreach就好啦~  里面的一大堆input只是样式啦~

\"\"\"\"
 1 @extends(\'admin::layouts.master\')
 2 @section(\'content\')
 3     @component(\'components.tabs\',[\' \'=>$role-> .\'权限设置\'])
 4         @slot(\'nav\')
 5             <li class=\"nav-item\"><a href=\"/admin/role\" class=\"nav- \">角色列表</a></li>
 6             <li class=\"nav-item\"><a href=\"#\" class=\"nav-  active\">权限设置</a></li>
 7         @endslot
 8         @slot(\'body\')
 9             <form action=\"/admin/role/permission/{{$role[\'id\']}}\" method=\"post\">
10                 @csrf
11                 @foreach($modules as $module)
12                     <div class=\"card-body pb-0\">
13                         @foreach($module[\'rules\'] as $rule)
14                             <div class=\"card card-flat\">
15                                 <div class=\"card-header\">{{$rule[\'group\']}}</div>
16                                 <div class=\"col-12 col-sm-8 col-lg-6 form-check mt-2\">
17                                     @foreach($rule[\'permissions\'] as $k=>$permission)
18                                         <p hidden>{{$i = $k + rand(0,1000000)}}</p>
19                                         <div class=\"checkboxWrapper theme3 extraSmallCheckboxSize mr-3\"
20                                              style=\"float: left;\">
21                                             <input type=\"checkbox\" name=\"name[]\" id=\"sample{{$i}}\"
22                                                    {{$role->hasPermissionTo($permission[\'name\'])?\'checked=\"\"\':\'\'}} value=\"{{$permission[\'name\']}}\">
23                                             <label for=\"sample{{$i}}\">
24                                                 <i>
25                                                     <svg version=\"1.1\" id=\" _1\"  ns=\"http://www.w3.org/2000/svg\"
26                                                           ns:x =\"http://www.w3.org/1999/x \" x=\"0px\" y=\"0px\"
27                                                          width=\"50px\" height=\"50px\" viewBox=\"0 0 50 50\"
28                                                          enable-background=\"new 0 0 50 50\"  :space=\"preserve\">
29                     <circle fill=\"none\" stroke=\"#B7B7B7\" stroke-width=\"3\" stroke-miterlimit=\"10\" cx=\"25.11\" cy=\"24.883\"
30                             r=\"23.519\"/>
31                                                         <path fill=\"none\" stroke-width=\"3\" stroke-miterlimit=\"10\" d=\"M48.659,25c0,12.998-10.537,23.534-23.534,23.534
32                     S1.591,37.998,1.591,25S12.127,1.466,25.125,1.466c9.291,0,17.325,5.384,21.151,13.203L19,36l-9-14\"/>
33                 </svg>
34                                                 </i>
35                                                 <span style=\"float: right;margin-top: 3px;font-size: 14px;margin-left: 5px\">{{$permission[\' \']}}</span>
36                                             </label>
37                                         </div>
38                                     @endforeach
39                                 </div>
40                             </div>
41                         @endforeach
42                     </div>
43                 @endforeach
44                 <button class=\"btn btn-primary\">保存</button>
45             </form>
46         @endslot
47     @endcomponent
48 @endsection
permiss.blade.php

3. 给用户设置权限

1 public function permissionStore(Request $request, Role $role)
2 {
3     $role->syncPermissions($request->name); // 同步权限
4     session()->flash(\'success\', \'修改权限成功\');
5 
6     return back();
7 }

4. 根据用户来控制后台侧边导航栏的显示

  4.1 初始化管理员角色

    4.1.1 分配角色 —— 角色属于那个模型

      解释:因为CMS系统是多模块的,那么角色就得和不同模块绑定关系,不绑定就不可能操作该模块

      $user->assignRole([\'super_user\', \'admin\']);

      注意:Laravel默认是没有这方法的,所以需要拓展模型(模拟多继承)

 1 <?php
 2 
 3 namespace App;
 4 
 5 use Illuminate\\Notifications\\Notifiable;
 6 use Illuminate\\Foundation\\Auth\\User as Authenticatable;
 7 use Spatie\\Permission\\Traits\\HasRoles;
 8 
 9 class Admin extends Authenticatable
10 {
11     use Notifiable;
12     use HasRoles;
13 }

  4.2 侧边导航栏显示

    目的:给用户分配了什么权限,侧边导航栏就显示相应的权限链接

    实现:

      1. 再Config文件当中,将menus.php 和 permission.php 的 permission配置项进行统一

      2. 修改_menus.blade.php文件

 1 <div class=\"left-sidebar-scroll\">
 2     <div class=\"left-sidebar-content\">
 3         <ul class=\"sidebar-elements\">
 4             @foreach(\\HDModule::getMenus() as $moduleName => $groups)
 5                 @foreach($groups as $group)
 6                     <li class=\"divider\">{{$group[\' \']}}</li>
 7                     <li class=\"parent open\">
 8                         <a href=\"#\"><i class=\"{{$group[\'icon\']}}\"></i>&nbsp;<span>{{$group[\' \']}}</span></a>
 9                         <ul class=\"sub-menu\">
10                             @foreach($group[\'menus\'] as $menu)
11                                 @can($menu[\'permission\'])
12                                     <li>
13                                         <a href=\"{{$menu[\'url\']}}\" pjax><i
14                                                     class=\"{{$menu[\'icon\']}}\"></i><span>&nbsp;{{$menu[\' \']}}</span></a>
15                                     </li>
16                                 @endcan
17                             @endforeach
18                         </ul>
19                     </li>
20                 @endforeach
21             @endforeach
22         </ul>
23     </div>
24 </div>

        解释:@can是laravel的指令,用来检查用户是否具有某种权限

5. 站长权限(超级管理员权限)

  5.1 对laravel-permission的致敬

    我使用的laravel-module中是有对laravel-permission的一个改良,比如对中间件验证权限的改良(larave-permission处理不够灵活并对资源控制器支持不好)

    laravel-module:

     1. 在进行store和update的权限验证时,会自动对跳转到create、edit进行验证

     2. 在进行站长权限判断时,一步即可(而laravel-permission需要先进行用户属于什么角色判断,再进行有什么权限判断两步)

  5.2 修改Config/menus.php和Config/permission.php文件

    之前在这两个文件中,对permission配置项进行了语义化的书(比如Admin模块下的角色管理中的permission配置项写的是Admin::config-roles),但其实这2个文件并不对用户开放,且一旦系统成型修改不大,所以运用了以下写法

\"\"\"\"
 1 <?php return [
 2     0 =>
 3         [
 4             \' \'      => \'系统管理\',
 5             \'icon\'       => \'fa fa-navicon\',
 6             \'permission\' => [\'Modules\\Admin\\Http\\Controllers\\RoleController@index\'],
 7             \'menus\'      =>
 8                 [
 9                     [
10                         \' \'      => \'角色管理\',
11                         \'icon\'       => \'fa fa-user-md\',
12                         \'permission\' => \'Modules\\Admin\\Http\\Controllers\\RoleController@index\',
13                         \'url\'        => \'/admin/role\',
14                     ],
15                 ],
16         ],
17 ];
menus.php
\"\"\"\"
 1 <?php
 2 /**
 3  * 权限配置
 4  * 为了避免其他模块有同名的权限,权限标识要以 \'控制器@方法\' 开始
 5  */
 6 return [
 7     [
 8         \'group\'       => \'角色管理\',
 9         \'permissions\' => [
10             [
11                 \' \' => \'角色列表\',
12                 \'name\'  => \'Modules\\Admin\\Http\\Controllers\\RoleController@index\',
13                 \'guard\' => \'admin\',
14             ],
15             [
16                 \' \' => \'添加角色\',
17                 \'name\'  => \'Modules\\Admin\\Http\\Controllers\\RoleController@create\',
18                 \'guard\' => \'admin\',
19             ],
20             [
21                 \' \' => \'删除角色\',
22                 \'name\'  => \'Modules\\Admin\\Http\\Controllers\\RoleController@destory\',
23                 \'guard\' => \'admin\',
24             ],
25             [
26                 \' \' => \'修改角色\',
27                 \'name\'  => \'Modules\\Admin\\Http\\Controllers\\RoleController@edit\',
28                 \'guard\' => \'admin\',
29             ],
30             [
31                 \' \' => \'修改角色权限\',
32                 \'name\'  => \'Modules\\Admin\\Http\\Controllers\\RoleController@permission\',
33                 \'guard\' => \'admin\',
34             ],
35         ],
36     ],
37 ];
permission.php

  修改之后,相应的_menus.blade.php也需要进行修改

\"\"\"\"
 1 <div class=\"left-sidebar-scroll\">
 2     <div class=\"left-sidebar-content\">
 3         <ul class=\"sidebar-elements\">
 4             @foreach(\\HDModule::getMenus() as $moduleName => $groups)
 5                 @foreach($groups as $group)
 6                     <li class=\"divider\">{{$group[\' \']}}</li>
 7                     <li class=\"parent\">
 8                         @if(\\HDModule::hadPermission($group[\'permission\'],\'admin\'))
 9                             <a href=\"#\"><i class=\"{{$group[\'icon\']}}\"></i>&nbsp;<span>{{$group[\' \']}}</span></a>
10                             <ul class=\"sub-menu\">
11                                 @foreach($group[\'menus\'] as $menu)
12                                     @if(\\HDModule::hadPermission($menu[\'permission\'],\'admin\'))
13                                         <li>
14                                             <a href=\"{{$menu[\'url\']}}\" pjax><i
15                                                         class=\"{{$menu[\'icon\']}}\"></i><span>&nbsp;{{$menu[\' \']}}</span></a>
16                                         </li>
17                                     @endif
18                                 @endforeach
19                             </ul>
20                     </li>
21                     @endif
22                 @endforeach
23             @endforeach
24         </ul>
25     </div>
26 </div>
_menus.blade.php

  5.3 站长权限配置

    整个站都是属于他/她的,所以不需要对其进行验证

   5.3.1 确定站长

    运行 php artisan vender:publish --provider=\"Houdunwang\\Module\\LaravelServiceProvider\"

   在config/hd_module中就会有webmaster配置项啦

  5.3.2 忽略检测站长权限

    只需要将用户标识和webmaster配置项对应即可

  5.3.3 添加中间件

    在进行后台的任何操作时候,就需要进行中间件来判断是否该用户是站长

    此时就需要路由

 1 <?php
 2 
 3 Route::group(
 4     [\'middleware\' => \'web\', \'prefix\' => \'admin\', \'namespace\' => \'Modules\\Admin\\Http\\Controllers\'],
 5     function () {
 6         Auth::routes();
 7     }
 8 );
 9 
10 Route::group(
11     [\'middleware\' => [\'web\', \'auth:admin\'], \'prefix\' => \'admin\', \'namespace\' => \'Modules\\Admin\\Http\\Controllers\'],
12     function () {
13         // 后台首页
14         Route::get(\'/\', \'AdminController@index\');
15 
16         // 角色管理
17         Route::resource(\'role\', \'RoleController\')->middleware(\'permission:superAdmin\');
18 
19         // 权限管理
20         Route::get(\'role/permission/{role}\', \'RoleController@permission\')->middleware(\'permission:superAdmin\');
21         Route::post(\'role/permission/{role}\', \'RoleController@permissionStore\')->middleware(\'permission:superAdmin\');
22     }
23 );

    注意:

      1. 这个中间件是路由中间件,所以需要到app/Http/Kernel.php中进行注册(之后所以自定义的中间件都是如此,只是需要注册在相应位置即可)

      2. middleware(\'permission:admin\');中的admin参数是守卫者不是webmaster配置项

      3.middleware(\'permission:admin,resource\');中的resource参数时针对resource路由才添加

        \'permission\' => \\Houdunwang\\Module\\Middlewares\\PermissionMiddleware::class,

6. 零碎

  6.1 修复Vue模板中不能使用JS的情况

    需要使用@yield(\"\")占位符,不然会报Vue模板错误

  6.2 模型删除操作和表外键约束注意事项

    站长可不敢删除啊

    依赖表数据变化,本表数据删除

收藏 打印