使用二进制权限控制
/*
引言:
使用二进制权限控制,可以减少程序的逻辑判断,如有50 种权限需要验证,
一般会写 if...else if...else if 或 if(n==1 || n==2 || ... n=50 )
这种写法。
如果使用二进制权限控制,则可使用一个if即可验证 if((权限码|n)==n),
注意 n 必须为 2的幂级。
c#中标记[System.Flags]特性的枚举,实质上是就是这种鉴权方式。
[System.Flags]
public enum Role
{
read = 1, //001
write = 2, //010
delete= 4, //100
}
使用建议:权限被频繁验证,权限值多于32个
定义:
授权码:权限值的集合表示
授权值:单个权限值,该值必须为2的幂级数,取值范围 2^0 到 2^62
授权:“权限码”=“权限”组每项进行“或”操作)
回收:待收回的“权限”取反后,和“授权码”进行“与”操作
鉴权:有两个公式:“权限”=“授权码”&“权限”;“授权码”=“授权码”|“权限”;
1.权限值
long类型可表示的2的最大幂级数为:4611686018427387904
转为二进制数表示为:10000000...000(共63位;一个1,六十二个0;表示为2^62)
加上2^0=1 ,所以1个long最多可以表示 63 个状态,2^0 到 2^62 次方;
实例:
bin name 授权码
0001 添加 (1)
0010 修改 (2)
0100 删除 (4)
1000 查看 (8)
0011 表示:添加 + 修改 权限
1011 表示:查看 + 修改 + 添加 权限
2.授权(“权限码”=“权限”组每项进行“或”操作)
授予 (添加 + 修改) 权限
0011 = 0001 | 0010
0011 => 3
3=1|2
select bin(3),bin(1),bin(2),bin(1|2);
授予 (查看 + 修改 + 添加) 权限
1011 = 0001 | 0010 | 1000
1011 => 11 #转为十进制数
11= 1|2|8 #十进制数运算
select bin(11),bin(1),bin(2),bin(8),bin(1|2|8);
3.回收权限(待收回的“权限”取反后,和“授权码”进行“与”操作)
公式:code = code&(~num)
1>A =(查看 + 修改 + 添加) 组合
1011 = 0001 | 0010 | 1000
11= 1|2|8 #十进制数运算
2>回收 A 的"添加"权限
1010 = 1011 & (~0001)
1010 => 10 = 11&(~1)
select bin(11&(~1)),11&(~1);
4.鉴权
公式1:num = code & num; (“权限”=“授权码”&“权限”)
公式2:code = code | num; (“授权码”=“授权码”|“权限”)
注:“权限” 必须为 2 的幂级数,否则会出错。
1>A =(查看 + 修改 + 添加) 组合
1011 = 0001 | 0010 | 1000
11= 1|2|8 #十进制数运算
2>鉴权
鉴权1
select 11&4; #与 4 等于 0,无权限
select 11&8; #与 8 等于 8,有权限
鉴权2
select 11|4; #或 4 不等于 11,无权限
select 11|8; #或 8 等于 11,有权限
5.错误鉴权值,及非2的幂级,实例
错误鉴权1
select 11&3; #与 3 等于 3,错误
select 11&9; #与 9 等于 9,错误
错误鉴权2
select 11|3; #或 3 等于 11,错误
select 11|9; #或 9 等于 11,错误
*/
SELECT POWER(2,0),POWER(2,1),POWER(2,2),POWER(2,64);
SELECT BIN(1),BIN(~1),BIN(POWER(2,50));
#菜单表
SELECT * FROM `wdt_base_menu`;
#权限表
SELECT * FROM `wdt_base_authority`;
#角色表
SELECT * FROM `wdt_base_role`;
#角色授权表
SELECT * FROM `wdt_base_roleauthority`;
#查询角色包含的菜单
SELECT *
FROM `wdt_base_menu`
WHERE Authoritys&16383=Authoritys AND module=1;
引言:
使用二进制权限控制,可以减少程序的逻辑判断,如有50 种权限需要验证,
一般会写 if...else if...else if 或 if(n==1 || n==2 || ... n=50 )
这种写法。
如果使用二进制权限控制,则可使用一个if即可验证 if((权限码|n)==n),
注意 n 必须为 2的幂级。
c#中标记[System.Flags]特性的枚举,实质上是就是这种鉴权方式。
[System.Flags]
public enum Role
{
read = 1, //001
write = 2, //010
delete= 4, //100
}
使用建议:权限被频繁验证,权限值多于32个
定义:
授权码:权限值的集合表示
授权值:单个权限值,该值必须为2的幂级数,取值范围 2^0 到 2^62
授权:“权限码”=“权限”组每项进行“或”操作)
回收:待收回的“权限”取反后,和“授权码”进行“与”操作
鉴权:有两个公式:“权限”=“授权码”&“权限”;“授权码”=“授权码”|“权限”;
1.权限值
long类型可表示的2的最大幂级数为:4611686018427387904
转为二进制数表示为:10000000...000(共63位;一个1,六十二个0;表示为2^62)
加上2^0=1 ,所以1个long最多可以表示 63 个状态,2^0 到 2^62 次方;
实例:
bin name 授权码
0001 添加 (1)
0010 修改 (2)
0100 删除 (4)
1000 查看 (8)
0011 表示:添加 + 修改 权限
1011 表示:查看 + 修改 + 添加 权限
2.授权(“权限码”=“权限”组每项进行“或”操作)
授予 (添加 + 修改) 权限
0011 = 0001 | 0010
0011 => 3
3=1|2
select bin(3),bin(1),bin(2),bin(1|2);
授予 (查看 + 修改 + 添加) 权限
1011 = 0001 | 0010 | 1000
1011 => 11 #转为十进制数
11= 1|2|8 #十进制数运算
select bin(11),bin(1),bin(2),bin(8),bin(1|2|8);
3.回收权限(待收回的“权限”取反后,和“授权码”进行“与”操作)
公式:code = code&(~num)
1>A =(查看 + 修改 + 添加) 组合
1011 = 0001 | 0010 | 1000
11= 1|2|8 #十进制数运算
2>回收 A 的"添加"权限
1010 = 1011 & (~0001)
1010 => 10 = 11&(~1)
select bin(11&(~1)),11&(~1);
4.鉴权
公式1:num = code & num; (“权限”=“授权码”&“权限”)
公式2:code = code | num; (“授权码”=“授权码”|“权限”)
注:“权限” 必须为 2 的幂级数,否则会出错。
1>A =(查看 + 修改 + 添加) 组合
1011 = 0001 | 0010 | 1000
11= 1|2|8 #十进制数运算
2>鉴权
鉴权1
select 11&4; #与 4 等于 0,无权限
select 11&8; #与 8 等于 8,有权限
鉴权2
select 11|4; #或 4 不等于 11,无权限
select 11|8; #或 8 等于 11,有权限
5.错误鉴权值,及非2的幂级,实例
错误鉴权1
select 11&3; #与 3 等于 3,错误
select 11&9; #与 9 等于 9,错误
错误鉴权2
select 11|3; #或 3 等于 11,错误
select 11|9; #或 9 等于 11,错误
*/
SELECT POWER(2,0),POWER(2,1),POWER(2,2),POWER(2,64);
SELECT BIN(1),BIN(~1),BIN(POWER(2,50));
#菜单表
SELECT * FROM `wdt_base_menu`;
#权限表
SELECT * FROM `wdt_base_authority`;
#角色表
SELECT * FROM `wdt_base_role`;
#角色授权表
SELECT * FROM `wdt_base_roleauthority`;
#查询角色包含的菜单
SELECT *
FROM `wdt_base_menu`
WHERE Authoritys&16383=Authoritys AND module=1;