一、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. 路由定义

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

2. 页面展示

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

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

方法一:遍历permission.php文件

方法二:通过方法来获取

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

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

 @extends('admin::layouts.master')
@section('content')
@component('components.tabs',['title'=>$role->title.'权限设置'])
@slot('nav')
<li class="nav-item"><a href="/admin/role" class="nav-link">角色列表</a></li>
<li class="nav-item"><a href="#" class="nav-link active">权限设置</a></li>
@endslot
@slot('body')
<form action="/admin/role/permission/{{$role['id']}}" method="post">
@csrf
@foreach($modules as $module)
<div class="card-body pb-0">
@foreach($module['rules'] as $rule)
<div class="card card-flat">
<div class="card-header">{{$rule['group']}}</div>
<div class="col-12 col-sm-8 col-lg-6 form-check mt-2">
@foreach($rule['permissions'] as $k=>$permission)
<p hidden>{{$i = $k + rand(0,1000000)}}</p>
<div class="checkboxWrapper theme3 extraSmallCheckboxSize mr-3"
style="float: left;">
<input type="checkbox" name="name[]" id="sample{{$i}}"
{{$role->hasPermissionTo($permission['name'])?'checked=""':''}} value="{{$permission['name']}}">
<label for="sample{{$i}}">
<i>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="50px" height="50px" viewBox="0 0 50 50"
enable-background="new 0 0 50 50" xml:space="preserve">
<circle fill="none" stroke="#B7B7B7" stroke-width="3" stroke-miterlimit="10" cx="25.11" cy="24.883"
r="23.519"/>
<path fill="none" stroke-width="3" stroke-miterlimit="10" d="M48.659,25c0,12.998-10.537,23.534-23.534,23.534
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"/>
</svg>
</i>
<span style="float: right;margin-top: 3px;font-size: 14px;margin-left: 5px">{{$permission['title']}}</span>
</label>
</div>
@endforeach
</div>
</div>
@endforeach
</div>
@endforeach
<button class="btn btn-primary">保存</button>
</form>
@endslot
@endcomponent
@endsection

permiss.blade.php

3. 给用户设置权限

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

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

4.1 初始化管理员角色

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

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

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

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

 <?php

 namespace App;

 use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles; class Admin extends Authenticatable
{
use Notifiable;
use HasRoles;
}

4.2 侧边导航栏显示

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

实现:

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

2. 修改_menus.blade.php文件

 <div class="left-sidebar-scroll">
<div class="left-sidebar-content">
<ul class="sidebar-elements">
@foreach(\HDModule::getMenus() as $moduleName => $groups)
@foreach($groups as $group)
<li class="divider">{{$group['title']}}</li>
<li class="parent open">
<a href="#"><i class="{{$group['icon']}}"></i>&nbsp;<span>{{$group['title']}}</span></a>
<ul class="sub-menu">
@foreach($group['menus'] as $menu)
@can($menu['permission'])
<li>
<a href="{{$menu['url']}}" pjax><i
class="{{$menu['icon']}}"></i><span>&nbsp;{{$menu['title']}}</span></a>
</li>
@endcan
@endforeach
</ul>
</li>
@endforeach
@endforeach
</ul>
</div>
</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个文件并不对用户开放,且一旦系统成型修改不大,所以运用了以下写法

 <?php return [
0 =>
[
'title' => '系统管理',
'icon' => 'fa fa-navicon',
'permission' => ['Modules\Admin\Http\Controllers\RoleController@index'],
'menus' =>
[
[
'title' => '角色管理',
'icon' => 'fa fa-user-md',
'permission' => 'Modules\Admin\Http\Controllers\RoleController@index',
'url' => '/admin/role',
],
],
],
];

menus.php

 <?php
/**
* 权限配置
* 为了避免其他模块有同名的权限,权限标识要以 '控制器@方法' 开始
*/
return [
[
'group' => '角色管理',
'permissions' => [
[
'title' => '角色列表',
'name' => 'Modules\Admin\Http\Controllers\RoleController@index',
'guard' => 'admin',
],
[
'title' => '添加角色',
'name' => 'Modules\Admin\Http\Controllers\RoleController@create',
'guard' => 'admin',
],
[
'title' => '删除角色',
'name' => 'Modules\Admin\Http\Controllers\RoleController@destory',
'guard' => 'admin',
],
[
'title' => '修改角色',
'name' => 'Modules\Admin\Http\Controllers\RoleController@edit',
'guard' => 'admin',
],
[
'title' => '修改角色权限',
'name' => 'Modules\Admin\Http\Controllers\RoleController@permission',
'guard' => 'admin',
],
],
],
];

permission.php

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

 <div class="left-sidebar-scroll">
<div class="left-sidebar-content">
<ul class="sidebar-elements">
@foreach(\HDModule::getMenus() as $moduleName => $groups)
@foreach($groups as $group)
<li class="divider">{{$group['title']}}</li>
<li class="parent">
@if(\HDModule::hadPermission($group['permission'],'admin'))
<a href="#"><i class="{{$group['icon']}}"></i>&nbsp;<span>{{$group['title']}}</span></a>
<ul class="sub-menu">
@foreach($group['menus'] as $menu)
@if(\HDModule::hadPermission($menu['permission'],'admin'))
<li>
<a href="{{$menu['url']}}" pjax><i
class="{{$menu['icon']}}"></i><span>&nbsp;{{$menu['title']}}</span></a>
</li>
@endif
@endforeach
</ul>
</li>
@endif
@endforeach
@endforeach
</ul>
</div>
</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 添加中间件

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

此时就需要路由

 <?php

 Route::group(
['middleware' => 'web', 'prefix' => 'admin', 'namespace' => 'Modules\Admin\Http\Controllers'],
function () {
Auth::routes();
}
); Route::group(
['middleware' => ['web', 'auth:admin'], 'prefix' => 'admin', 'namespace' => 'Modules\Admin\Http\Controllers'],
function () {
// 后台首页
Route::get('/', 'AdminController@index'); // 角色管理
Route::resource('role', 'RoleController')->middleware('permission:superAdmin'); // 权限管理
Route::get('role/permission/{role}', 'RoleController@permission')->middleware('permission:superAdmin');
Route::post('role/permission/{role}', 'RoleController@permissionStore')->middleware('permission:superAdmin');
}
);

注意:

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 模型删除操作和表外键约束注意事项

站长可不敢删除啊

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

Laravel系列之CMS系统学习 — 角色、权限配置【2】的更多相关文章

  1. Laravel系列之CMS系统学习 — 角色、权限配置【1】

    一.后台Admin模块 后台管理是有管理员的,甚至超级管理员,所以在设计数据表的时候,就会有2个方案,一个方案是共用users数据表,添加is_admin,is_superAdmin字段来进行验证,或 ...

  2. Laravel系列教程一:安装及环境配置

    免费视频教程地址https://laravist.com/series/laravel-5-basic 最近在SF上面看到越来越多的Laravel相关的问题,而作为一个Laravel的脑残粉,本来打算 ...

  3. 一百一十一:CMS系统之后端权限验证功能

    实现方式 使用装饰器的形式,将权限判断加在视图上 声明接口需要什么权限,用户访问接口的时候,判断用户是否有此权限 权限判断,接收权限 def permission_required(permissio ...

  4. 一百零八:CMS系统之封装权限判断功能

    在用户模型下定义属性和方法,用于判断用户的权限 @propertydef permissions(self): """ 返回用户拥有的所有权限 ""& ...

  5. STM32入门系列-STM32时钟系统,时钟使能配置函数

    之前的推文中说到,当使用一个外设时,必须先使能它的时钟.怎么通过库函数使能时钟呢?如需了解寄存器配置时钟,可以参考<STM32F10x中文参考手册>"复位和时钟控制(RCC)&q ...

  6. STM32入门系列-STM32时钟系统,时钟初始化配置函数

    在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main.那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使 ...

  7. Laravel系列 Web

    一.Homestead准备 上一篇文章已经对它的配置进行了说明,下面对Homestead.yaml进行说明 --- ip: "192.168.10.10" memory: 2048 ...

  8. Dubbo -- 系统学习 笔记 -- 配置参考手册

    Dubbo -- 系统学习 笔记 -- 目录 配置参考手册 <dubbo:service/> <dubbo:reference/> <dubbo:protocol/> ...

  9. Dubbo -- 系统学习 笔记 -- 配置

    Dubbo -- 系统学习 笔记 -- 目录 配置 Xml配置 属性配置 注解配置 API配置 配置 Xml配置 配置项说明 :详细配置项,请参见:配置参考手册 API使用说明 : 如果不想使用Spr ...

随机推荐

  1. NGUI动态字体的使用

    LZ今年六月刚刚毕业,在学校跟着老师做Android,OpenGL ES方面的项目(说白了就是干苦力╮(╯_╰)╭).年后来SZ了,就业前景好像并没有电视上渲染的那样糟糕,至少IT行业是这样吧,只要你 ...

  2. JavaScript的数据类型与变量

    JavaScript数据类型 1.原始数据类型: 数值型,如十进制数.十六进制数.八进制数和特殊值(Infinity.NaN),注意:NaN不能和自身比较 字符串型,如定界符.转义符: 布尔类型. 2 ...

  3. Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别? 线程的sleep()方法和yield()方法有什么区别?

    Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别? sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间 ...

  4. web Worker基本使用

    web worker 使用 web worker 是现代浏览器具有的可以处理密集型任务非常便利的解决方案,众所周知,JavaScript是单线程的(一个JavaScript引擎实例只能占用一个线程,线 ...

  5. 再学UML-Bug管理系统UML2.0建模实例(二)

    2.3 BMS顺序图(需求模型)       在UML中,我们将顺序图分为两类,一类用于描述系统需求,构造系统的需求模型(分析模型):另一类用于指导设计与实现,构造系统的实现模型(设计模型).     ...

  6. oracle_set_autocommit

    preface 1.centos  operating  system. 2.database is oracle 11g. 3.oracle account  is  scott. step 1.e ...

  7. May 17th 2017 Week 20th Wednesday

    Men are nearly always willing to believe what they wish. 人总爱想入非非,把愿望变成现实. It is just the humancondit ...

  8. [EffectiveC++]item30:Understand the ins and outs of inlining

  9. bootstrap-multiselect.js如何动态更新select里的数据

    在使用jQuery的bootstrap-multiselect插件时可能会遇到一个问题 就是想要动态的去更新select里的数据 比如我们要使一个id=select的选择框实现多选 那么先用ajax获 ...

  10. 【洛谷5294】[HNOI2019] 序列(主席树维护单调栈+二分)

    点此看题面 大致题意: 给你一个长度为\(n\)的序列\(A\),每次询问修改一个元素(只对当前询问有效),然后让你找到一个不下降序列\(B\),使得这两个序列相应位置之差的平方和最小,并输出这个最小 ...