今天学习了一个比较有趣的权限模型。
比如用户在一个系统中有不同的权限,这些权限称为一个权限组:
1、管理员权限: 管理员,拥有系统所有权限。
2、普通权限:一般用于普通成员,只拥有家庭数据查看,设备、场景控制,接收通知等普通权限。
3、高级权限:针对特殊用户设置的权限角色, 除拥有普通权限外, 还拥有有限的功能管理权限。
不同的权限有不同的功能点
按照业务模块分类划分功能权限,同时考虑c端交互特点,已功能有限性(预估每??樾∮?0个),可采用二进制位定义权限点取值, 那么用户拥有的某个??槿ㄏ尬诟媚?橄掠涤械母魅ㄏ薜闳≈抵?。
??槟谌ㄏ薜阈蚝糯?开始递增, 那么可按照公式:
权限点取值 = 2^(权限点序号-1)
设计缘由
权限值是这样的
2^0=1,相应2进数为”0001″(在这里^我表示成”次方”,即:2的0次方,下同)
2^1=2,相应2进数为”0010″
2^2=4,相应2进数为”0100″
2^3=8,相应2进数为”1000″
要判断一个数在某些数范围内就可以使用 & 运算符(数值从上面的表中得来)
如:7=4|2|1 (由于是2的倍数,你也可以简单理解成7=4+2+1)
用 & 来操作,可以知道7&4、7&2、7&1都是真的,而如果7&8则是假的
/**
* 权限值计算
*/
public long getPrivilegeValue() {
return (long) Math.pow(2, (this.seq - 1));
}
/**
* 权限值求和
*/
sum |= item.getPrivilegeValue();
代码流程简述
1,权限配置在apollo中,由于使用的是ConfigurationProperties注解,更改不会自动更新,而且需要转下格式,使用ApolloConfigChangeListener进行监听
@ApolloConfigChangeListener
private void onKeyChange(ConfigChangeEvent changeEvent) {
Set<String> changedKeys = changeEvent.changedKeys();
for (String key : changedKeys) {
if (key.equals("family.privilege.settings")) {
//转换格式
this.refreshFamilyPrivilegeSettings();
}
}
//更新配置
this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
}
private void refreshFamilyPrivilegeSettings() {
Map<String, List<PrivilegeSettings>> newSettingsMap = Maps.newHashMap();
//xxx 解析;格式:{"priv.family":[{"groups":[1,2,3],"seq":1},{"groups":[1],"seq":2},{"groups":[1],"seq":3}]}
settingsMap = newSettingsMap;
}
2,通过privilegeGroup(比如2:普通权限),就可以获取到各个??橹С值墓δ苋ㄏ薜?/p>
3,通过 sum |= item.getPrivilegeValue();获取到各个??榈娜ㄏ拗岛?/p>
{
"priv.family-member": 1,
"priv.family": 1,
"priv.family-scene": 35,
"priv.family-config": 3,
"priv.family-device": 1027,
"priv.family-room": 1
}
4,若想要判断该用户是否有某个模块某个功能的权限,只需先判断用户在哪个权限组,根据??閗ey获取到对应功能值。与上面获取到的sum取&,若大于0则代表有该功能的权限。