当前位置: 首页 > Web前端 > JavaScript

基于位操作的权限设计

时间:2023-03-27 14:04:29 JavaScript

基于位运算的权限设计因为这里的权限是基于位的,所以大家需要对位和位运算符有一定的了解[TOC]预知MDN位运算符的权限是单一的,从右到左只有一位是1,从低位到高位运算符简写:&按位与:如果对应位全为1,则为1|按位或:如果对应的位全为0,则为0,实际情况为1。我们以4个权限的CRUD为例,用4个位来执行。这里需要注意一点,单个权限有且只有一位为1变量二进制描述C0b0001增加D0b0010删除U0b0100更改R0b1000查询部分权限constcurPermission=0b1001;//当前用户权限,"增加""检查"constallowCreate=(curPermission&C)===C;//=>trueconstallowUpdate=(curPermission&U)===U;//=>false从上面的代码可以看出,当前用户的权限是Ob1001的第一位和第二位四位都是1,代表你有权限增查。当用户的权限使用bitwise且只有相同的位为1时,可以得到1。从图和代码可以看出,我们可以比较使用&定义好得到的值。变量是否相等,是否有某权限加某权限letcurPermission=0b0100;//当前用户只有“更改”权限//C=0b0001D=0b0010//添加“添加”和“删除”权限curPermission=curPermission|丙|你;//=>0b0111最后,我们得到的权限包括原来的“更改”和新增的“添加”和“删除”。用&(~P)操作letcurPermission=0b1110;//当前用户权限,“删除”、“修改”、“检查”//R=0b1000curPermission=curPermission&~C;//=>Ob0110delete"check"权限最后,我们得到的权限只有“delete”和“change”。“检查”权限已被删除。Toggle运算采用按位异或,无则增减(对应位不同为1,相同为0)。从实际结果来看一个Toggle操作letcurPermission=0b1000;//当前用户权限,“检查”//如果没有则增加;C=0b0001curPermission^C;//=>Ob1001get"increase""check"//decreasecurPermission^C;//=>Ob1001获得“check”,并从复合类型中删除“increase”权限。我们可以使用复合操作来进行更方便快捷的操作,它可以用于以上任何一种操作。这里我们仅以验证为例。当我们的页面有下图的操作栏,同时有删除按钮和修改按钮时,会出现以下几种情况:当有“删除”权限时,显示删除按钮;当有“更改”权限时,会显示“编辑”按钮。当没有“删除”和“修改”时,隐藏操作栏constcurPermission=0b1000;//当前用户权限constD=0b0010;//删除常量U=0b0100;//改变constDandU=0b0110;//delete和change都有constallowDelete=(p:number)=>(p&D)===D;constallowUpdate=(p:number)=>(p&U)===U;constallowDeleteAndUpdate=(p:number)=>(p&DandU)===DandU;constCOLUMNS=[{title:'operation',dataIndex:'operation',render:()=>(<>{allowUpdate(curPermission)&&}{allowDelete(curPermission)&&}),},];constretColumns=列。过滤器((x)=>{我f(x.dataIndex==='operation'){returnallowDeleteAndUpdate(curPermission);}returntrue;});//retColumns就是我们最终使用的Table列数据。同样,代码中的复合类型可以应用到其他Operation,有兴趣做作业的同学可以利用编码优势。一个参数可以代表多种类型,可以使用多种类型的权限码。比如既有新增又有修改,可以定义cosntallowCreateAndUpdate=0b1010。当使用(curAccess&allowCreateAndUpdate)===allowCreateAndUpdate时具有很高的可扩展性。例如,如果添加可执行权限,则可以使用5位位0b10000缺陷位运算符将其操作数视为32位二进制字符串——来自MDN。可用权限的数量是有限的,您可以使用结构或命名空间来控制结构,这些结构是对象。我们把具体的权限放在预定的结构体中constpermissionList=[{pid:1,//positionid也就是positionIDcode:0b0001,//对应的code}];命名空间,其实也可以用上面的结构描述,这里我们用字符串来描述,有一套默认的规则:pos,codeconstpermissionList=['pos1,0b0001','pos2,0b0011'];在具体使用中,根据自己不同的规则编写相应的权限操作方法,提供给具体的业务同学使用TypeScript添加使用Enum和位赋值运算符和命名空间的静态方法/**Definition*/enumAuthCode{read=0b001,//也可以写成1Write=0b010,//也可以写成r<<1or2/**executeexecute*/Exec=0b100,//也可以写成r<<2or4//下面是复合类型/**0b011*/ReadAndWrite=0b011,/**Unionofallhostauth*/HostAuthMask=0b111,}namespaceAuth{/***验证当前权限是否存在*@paramvalidCode-需要验证的权限代码(即用户返回的代码)*@paramcode-定义授权码*/exportconstvalidator=(validCode:AuthCode,code:AuthCode):boolean=>{return(validCode&code)===code;};//curryprocessingvalidator()/***给用户添加权限*@paramuserCode-当前用户的权限*@paramwaitingCode-要给用户添加的权限*@returns添加权限后返回所有权限*/exportconstadd=(userCode:AuthCode,waitingCode:AuthCode|AuthCode[]):AuthCode=>{letcode:number;}if(Array.isArray(waitingCode)){code=waitingCode.reduce((acc,cur)=>{returnacc|cur;},0);}else{code=waitingCode;}返回用户代码|代码;};/***删除用户的权限*@paramuserCode-当前用户的权限*@paramrmCode-要删除的权限*/exportconstremove=(userCode:AuthCode,rmCode:AuthCode|AuthCode[]):AuthCode=>{让代码:数字;如果(数组.isArray(rmCode)){code=rmCode.reduce((acc,cur)=>{returnacc|cur;},0);}else{code=rmCode;}返回用户代码&~code;};/***用户权限切换*@description如果没有则增加,如果有则减少*@paramuserCode-当前用户的权限*@paramtglCode-切换的权限*/exportconsttoggle=(userCode:AuthCode,tglCode:AuthCode)=>{returnuserCode^tglCode;};}//测试验证器//constuserCode=0b011;//获取用户在当前页面的权限码(读、写)//console.log(Auth.validator(userCode,AuthCode.Read));//=>真;当前用户有读取权限//console.log(Auth.validator(userCode,AuthCode.ReadAndWrite));//=>真;当前用户有读写权限//console.log(Auth.validator(userCode,AuthCode.Exec));//=>假的;当前用户没有权限执行//console.log(Auth.validator(userCode,AuthCode.Read|AuthCode.Exec));//=>假的;当前用户没有读取和执行权限;两个权限都为真//testadd//letuserCode=0b000;//获取当前页面用户的权限码(无权限)//console.log((userCode=Auth.add(userCode,AuthCode.Read)));//=>;1===0b001;为当前用户添加读取权限//console.log(Auth.validator(userCode,AuthCode.Read));//=>真;验证当前用户是否有读取权限//console.log(Auth.validator(userCode,AuthCode.Write));//=>假的;验证当前用户没有写入权限//console.log((userCode=Auth.add(userCode,[AuthCode.Write,AuthCode.Exec])));//=>7===0b111;为当前用户添加写入和执行权限//console.log(Auth.validator(userCode,AuthCode.HostAuthMask));//=>真;验证当前用户是否拥有所有权限//testremove//letuserCode=0b111;//获取当前页面用户的权限码(所有权限)//console.log(Auth.validator(userCode,AuthCode.HostAuthMask));//=>真;验证当前用户是否有权限//console.log((userCode=Auth.remove(userCode,AuthCode.Read)));//=>6===0b110;删除用户读取权限//console.log(Auth.validator(userCode,AuthCode.Read));//=>假的;验证当前用户是否移除了读取权限//console.log(//(userCode=Auth.remove(userCode,[AuthCode.Write,AuthCode.Exec]))//);//=>0===0b000;删除用户读取和执行权限//console.log(Auth.validator(userCode,AuthCode.Write));//=>假的;验证当前用户已被删除删除写权限//console.log(Auth.validator(userCode,AuthCode.Exec));//=>假的;验证当前用户是否删除了执行权限//testtoggle//letuserCode=0b101;//获取当前页面的用户权限码(执行、读取)//console.log((userCode=Auth.toggle(userCode,AuthCode.ReadAndWrite)));//=>6===0b110;当前用户删除读取,添加写入(如果没有写入则增加,如果读取则减少)//console.log(Auth.validator(userCode,AuthCode.Read));//=>假的;验证当前用户没有读取权限//console.log(Auth.validator(userCode,AuthCode.Write));//=>真;验证当前用户是否有写入权限参见https://segmentfault.com/a/11...https://juejin.cn/post/684490。..