Laravel系列之CMS系統學習 — 角色、許可權配置【2】

来源:https://www.cnblogs.com/ltqTest/archive/2018/12/11/10104843.html
-Advertisement-
Play Games

一、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 @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['title']}}</li>
 7                     <li class="parent open">
 8                         <a href="#"><i class="{{$group['icon']}}"></i>&nbsp;<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>&nbsp;{{$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>&nbsp;<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>&nbsp;{{$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 模型刪除操作和表外鍵約束註意事項

    站長可不敢刪除啊

    依賴表數據變化,本表數據刪除


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • java基礎之反射 1. 類的載入、連接和初始化 1.1 類的載入 1.2 類的連接 1.3 類的初始化 1.4 類載入器 2. 反射 2.1 反射基本信息 2.1.1 Class對象 2.1.2 Java反射機制的類庫支持 2.2 反射的基本實現 2.2.1 獲取Class對象 2.2.2 獲取構... ...
  • 1、Readme 文件,告訴別人如何使用你的程式(必須) 2、代碼加註釋,讓別人可以輕鬆讀懂你的代碼(必須) 3、目錄結構要符合規範,每天單獨一個目錄,如Day1,Day2,Day3..(必須) 4、流程圖,幫自己理清思路、幫別人更容易瞭解你的代碼設計邏輯(必須) 5、blog(博客),寫好blog ...
  • 在 Laravel 編寫單元測試時經常會遇到需要模擬認證用戶的時候,比如新建文章、創建訂單等,那麼在 Laravel unit test 中如何來實現呢? 官方解決方法 Laravel 的官方文檔中的測試章節中有提到: Of course, one common use of the session ...
  • Berlekamp Massey演算法 很久之前就聽說過這個演算法,當時六校聯考的時候Day1T1是一道很有意思的遞推,神仙zzx不會做於是就拿BM演算法艹出了遞推式Orzzzzzzzzzzx "推薦一篇講的詳細的不能再詳細的博客" 我就不詳細說了,只記一下自己感覺比較難理解的地方 設$r(m)$表示序列 ...
  • 前言 最近需要開發一個純API的項目,mlsql-cluster,從無到有,到最後完整的proxy功能開發完畢,只花了四個小時不到,自己不盡小感嘆了一把 ServiceFramework的高效。 關於ServiceFramework的誕生 ServiceFramework算是一個古老的,基於Java ...
  • 未壓縮前 ...
  • 上半節已經下載好了Zookeeper,以及新建了兩個應用provider和consumer,這一節我們就結合dubbo來測試一下分散式可不可以用。 現在就來簡單用一下,註意:這裡只是涉及最簡單的部分,新手入門用的,詳細的內容要學習的可以自己查一查資料;然後再說說用Zookeeper當作註冊中心的一個 ...
  • 第一個程式 print “Hello World!” print“Hello Again” print “I like type” print "This is fun." ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...