后台管理系统RABC通用权限控制规范与规范代码实施js-SDK,包含 节点/按钮/路由 等控制 ,
支持hidden,disabled,删除,或则自定义function处理。 通过配置实现RABC的权限控制
npm install⬆
npm i web-rabc-permissions-sdk -S
基本使用与设计思路⬆
设计思路:
- 每个web应用,初始的button、容器(div)、任意节点都是可见状态。本实例使用RABC设计思想,实现对web端权限进行控制。
- 正常情况下,用户成功登入系统,只需要配置用户不可使用的节点权限即可。
- 角色配置可以在一个.json里,也可以在一个专用的配置系统里,最佳选择在一个配置系统中,通过ajax读取,这样可以做到随时灵活的设置权限
- 非常规情况补充:
-
- 用户A与用户B,同时拥有角色1,但是用户A却需要在角色1的基础上拥有更多特性,则可通过用户A拥有多个角色进行补充;
- 用户A与用户B,同时拥有角色1,但是用户A却需要在不增加新角色的情况下,多一些button的控制,则单独设置havePermiss;
- 用户A与用户B,同时拥有角色1,但是用户A 需要某个时间段不拥有某些权限,则设置specialPermiss;
- 某些角色需要使用特定功能,比如使用vue某个 "template"内的方法或则Data,比如使用用户配置的自定义function
- 其中havePermiss 与 noPermiss 会进行 各自的routerPath 与 eleIdOrClass 简单diff判断,进行去重,得到一个以路由为属性的对象,通过当前路由与对象节点匹配,保证执行期间的最小次数。
- specialPermiss则作为特殊设置,满足特定需求
//基本使用代码如下
import {webRabcPermisson,getNewPermissionSimpleDTO,PLAN_ENUM,webRabcPermissionSdkOptions}
from 'web-rabc-permissions-sdk';
/*
webRabcPermissionSdkOptions :基本配置
PLAN_ENUM :执行计划(程序会自动做降级处理)
getNewPermissionSimpleDTO :每个路由下可能存在的权限
webRabcPermisson :实例类
*/
let _havePermissArr = [],
_noPermissArr = [],
_specialArr = [];
/*
假设请求一定成功
一般情况下,只需要配置用户或则对应角色不可拥有的节点
*/
ajax('get',url,{...userInfo}).then(res=>{
let {result} = res;
//角色 拥有的权限节点
_havePermissArr = result.map(i=>{
//得到实体构建节点对象
let _permissDTO = new getNewPermissionSimpleDTO();
//该节点的描述,方便debug理解,可空
_permissDTO.describe = `该节点的描述,方便debug理解,可空`;
//该节点ID或则className 其中id为 #id;className为 .className
_permissDTO.eleIdOrClass = `#id`
//hidden | removeNode 默认hidden,因为removeNode会直接导致DOM结构变更,可能造成副作用,本期暂未实现
_permissDTO.resultType = 'hidden'
//具体路由地址,程序执行会根据路由地址匹配,减少执行次数
_permissDTO.routerPath = '/c/vuepage1'
return _permissDTO
})
//角色 不可拥有节点
_noPermissArr= result.map(i=>{
//得到实体构建节点对象
let _permissDTO = new getNewPermissionSimpleDTO();
//该节点的描述,方便debug理解,可空
_permissDTO.describe = `该节点的描述,方便debug理解,可空`;
//该节点ID或则className 其中id为 #id;className为 .className
_permissDTO.eleIdOrClass = `.className`
//hidden | removeNode 默认hidden,因为removeNode会直接导致DOM结构变更,可能造成副作用,本期暂未实现
_permissDTO.resultType = 'hidden'
//具体路由地址,程序执行会根据路由地址匹配,减少执行次数
_permissDTO.routerPath = '/c/vuepage1'
return _permissDTO
})
//角色 不可拥有节点
_specialArr= result.map(i=>{
//得到实体构建节点对象
let _permissDTO = new getNewPermissionSimpleDTO();
//该节点的描述,方便debug理解,可空
_permissDTO.describe = `该节点的描述,方便debug理解,可空`;
//该节点ID或则className 其中id为 #id;className为 .className
_permissDTO.eleIdOrClass = `.className`
//hidden | removeNode 默认hidden,因为removeNode会直接导致DOM结构变更,可能造成副作用,本期暂未实现
_permissDTO.resultType = 'hidden'
//具体路由地址,程序执行会根据路由地址匹配,减少执行次数
_permissDTO.routerPath = '/c/vuepage1'
return _permissDTO
})
webRabcPermissionSdkOptions.havePermiss = _havePermissArr;
webRabcPermissionSdkOptions.noPermiss = _noPermissArr;
webRabcPermissionSdkOptions.specialPermiss = _specialArr;
//执行计划 MutationObserver or setTimeout
webRabcPermissionSdkOptions.plan = PLAN_ENUM.OB_SERVER;
//对象框架 目前支持获取vue this, react也适用,但是不能获取到某个react组件下的this
webRabcPermissionSdkOptions.libraryName = 'vue'
let _webRabc = new webRabcPermisson(webRabcPermissionSdkOptions);
//启动权限
_webRabc.start({
//执行时间
millisec:500,
//obServer的执行节点设置
obServerConfig:{
attributes:false,
childList:true,
subtree:true,
characterData:false
},
//节流时间
delay:500,
//必须指定一个observer的容器节点,必须是ID
obElem:'app'
});
})
//debug时 获取执行情况
console.dir(_webRabc.getSdkInfo())
具体使用的DEMO地址⬆
web-RABC-Permissions-sdk 使用DEMO地址
具体配置含义⬆
PLAN_ENUM(可选)⬆
- 执行计划枚举,在执行计划的时候通过选中方案进行执行。
- 如果不支持Mutation方案,则自动降级为setTimeout。
- 其中各方案带有节流,以便造成额外的性能开销。
- 默认方案为SET_TIMEOUT
属性名 | 描述 |
---|---|
SET_TIMEOUT | 通过setTimout实现执行方案 |
OB_SERVER | 通过MutationObserver实现执行方案 |
ACTION_ORDER(可选)⬆
- 设置当前web应用权限执行顺序逻辑
- 默认执行顺序 ---> 当前不可拥有权限 ---> 当前必须拥有权限 ---> 当前特定权限
属性名 | 描述 |
---|---|
doNoPermiss | 不可拥有 权限 |
doHavePermiss | 可拥有 权限 |
doSpecialPermiss | 特殊权限 |
permissionSimpleDTO(必选)⬆
- 设置当前web应用权限 havePermiss、noPermiss、specialPermiss 存储索引内容
- 每个节点固定DTO描述
属性名 | 是否必选 | 描述 |
---|---|---|
routerPath | 必选 | 当前路由关键字(react,vue,传统web应用), 也可以直接取"/",表示所有路由匹配 |
eleIdOrClass | 必选 | 当前节点的ID或则ClassName,若是ID,则赋值"#具体ID",若是className,则赋值".具体ClassName",最终通过querySelector和querySelectorAll获取,建议使用ID |
resultType | 可选 | 默认hidden |
showElemType | 可选 | 用户自定义display内容,设置后该节点将变为 display:用户内容!important;若赋值,则不会执行resultType逻辑 |
describe | 可选 | 节点描述,方便DEBUG查看具体含义,理论上为String类型最大值 |
callBackFunc | 可选 | 当前节点执行方法;默认不执行,若赋值,则只会执行当前callBackFunc(必须是一个function,箭头函数,class均会被throw),目前提供具体的4个方法,见如下代码,下个版本计划加入sandBox进行安全信任配置 |
vueTemplateRoot | 可选 | 当前节点可使用的vue对象,默认为""。若当前节点为正确的vue template ID,则可以在callBackFunc下得到当前vue 的this,通过this调用,若失败或则为"",this则为window |
//callBackFunc示例
callBackFunc = function(tools){
tools.$queryAll('.router_main i').forEach(i =>{
//你的业务逻辑
}
})
/*
其中tools包含
tools = {
$getById(el){
return document.getElementById(el)
},
$query(el){
return document.querySelector(el)
},
$queryAll(el){
return document.querySelectorAll(el)
},
$getTagName(el){
return document.getElementsByTagName(el)
}
}
若libraryName = 'vue' 且 节点vueTemplateRoot 指定为正确的vue template ,则callBackfunc下的this为当前vue对象,可对当前vue对象做任何操作
*/
webRabcPermissionSdkOptions(必选)⬆
- 实例构造的最基本DTO
属性名 | 是否必选 | 描述 |
---|---|---|
permission | 可选 | 为微前端保留的实体结构 |
libraryName | 可选 | 本次执行web应用中的基本框架,传入vue 或则 react,其中传入vue ,callBackFunc下获取library下对应的this对象有影响,不传入this默认指向window |
plan | 必选 | 执行方案,参见 PLAN_ENUM |
havePermiss | 可选 | 当前角色下必定显示的节点与路由集合(array) |
noPermiss | 可选 | 当前角色下 需要隐藏或则删除的节点与路由集合(array) |
specialPermiss | 可选 | 当前角色下 特殊的 节点与路由集合(array) |
actionOrder | 可选 | havePermiss、noPermiss、specialPermiss执行顺序,默认当前不可拥有权限 ---> 当前必须拥有权限 ---> 当前特定权限 |
启动权限⬆
let _webRabc = new webRabcPermisson(webRabcPermissionSdkOptions);
_webRabc.start({
//PLAN_ENUM.SET_TIMEOUT 的轮询间隔,也可以充当 PLAN_ENUM.OB_SERVER 的节流时间
millisec:500,
//PLAN_ENUM.OB_SERVER 的监控范围
obServerConfig:{
attributes:false,
childList:true,
subtree:true,
characterData:false
},
//PLAN_ENUM.OB_SERVER 的节流间隔
delay:500,
//PLAN_ENUM.OB_SERVER 下具体监控节点
obElem:'app'
});
工程架构总览与执行简述⬆
- 面向切面的编程思想
- 程序会在单例模式的基础上,返回现有实例,保证全局唯一。
- 通过内部类constructor 缓存最初传入参数与权限节点
- start()
-
- 首先会diff掉 拥有权限与没有权限的数据,解决互斥,减少操作DOM的情况。
- 根据routerPath 和 eleIdOrClass 进行权限节点是否相同的判断。
- 其次判断传入执行计划,若浏览器不支持,则降级为setTimeout作为执行计划。
- 若有function执行黑名单,则会throw错误(后续计划),用户可自由配置不允许操作的范围,比如cookie操作/localStorage操作等
- 最终根据执行计划,匹配当前路由与根据routerPath的关系,执行当前权限。
- 权限根据执行计划执行
继续开发计划⬆
- 增加sandBox(可选)
-
黑名单配置
-
运行时验证
-
start前验证
- 增加微前端模式
- 可配置执行浏览器空闲执行
- resultType增加removeNode逻辑实现
- 构建aio,es,umd区分