一、RBAC分析 基於角色的許可權訪問控制(Role-Based Access Control),這裡存在這麼幾個玩意兒:角色、許可權,用戶 表:roles、permissions、role_has_permissions、model_has_roles、model_has_permissions(最後 ...
一、RBAC分析
基於角色的許可權訪問控制(Role-Based Access Control),這裡存在這麼幾個玩意兒:角色、許可權,用戶
表:roles、permissions、role_has_permissions、model_has_roles、model_has_permissions(最後兩張表可以看4.1有解釋)
明確:用戶屬於什麼角色,那麼角色擁有什麼許可權,用戶自然擁有
然後配置,就戳這裡(後面就不添加了)~
二、角色的增刪改查
這個就很普通的功能了,略???
但是有一些需要註意的地方:
1. 更新操作時,method使用PUT
2. Laravel的唯一性驗證舉例:'title' => 'required|unique:roles,title,'.$id,
解釋:對title欄位進行驗證——必填|唯一性驗證:從拿一張表進行驗證,驗證什麼欄位,不驗證當前欄位(意思就是:比如你要修改的信息叫張三,表裡面只有你當前編輯的這條記錄是張三,所以忽略要這條記錄,不然不就不唯一了嘛~)
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',['title'=>$role->title.'許可權設置']) 4 @slot('nav') 5 <li class="nav-item"><a href="/admin/role" class="nav-link">角色列表</a></li> 6 <li class="nav-item"><a href="#" class="nav-link 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="Layer_1" xmlns="http://www.w3.org/2000/svg" 26 xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 27 width="50px" height="50px" viewBox="0 0 50 50" 28 enable-background="new 0 0 50 50" xml: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['title']}}</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 @endsectionpermiss.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['title']}}</li> 7 <li class="parent open"> 8 <a href="#"><i class="{{$group['icon']}}"></i> <span>{{$group['title']}}</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> {{$menu['title']}}</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 'title' => '系統管理', 5 'icon' => 'fa fa-navicon', 6 'permission' => ['Modules\Admin\Http\Controllers\RoleController@index'], 7 'menus' => 8 [ 9 [ 10 'title' => '角色管理', 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 'title' => '角色列表', 12 'name' => 'Modules\Admin\Http\Controllers\RoleController@index', 13 'guard' => 'admin', 14 ], 15 [ 16 'title' => '添加角色', 17 'name' => 'Modules\Admin\Http\Controllers\RoleController@create', 18 'guard' => 'admin', 19 ], 20 [ 21 'title' => '刪除角色', 22 'name' => 'Modules\Admin\Http\Controllers\RoleController@destory', 23 'guard' => 'admin', 24 ], 25 [ 26 'title' => '修改角色', 27 'name' => 'Modules\Admin\Http\Controllers\RoleController@edit', 28 'guard' => 'admin', 29 ], 30 [ 31 'title' => '修改角色許可權', 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['title']}}</li> 7 <li class="parent"> 8 @if(\HDModule::hadPermission($group['permission'],'admin')) 9 <a href="#"><i class="{{$group['icon']}}"></i> <span>{{$group['title']}}</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> {{$menu['title']}}</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 模型刪除操作和表外鍵約束註意事項
站長可不敢刪除啊
依賴表數據變化,本表數據刪除