不管是前端还是后端的伙伴,在工作中会经常遇到权限控制的场景,业务上无非就几种权限:页面权限
、操作权限
、数据权限
,不同公司根据业务需要都采取不同的方法区控制权限,我们这里讨论一下使用 JS 中的位运算符来控制权限。
进制类型
JavaScript 中提供的进制表示方法有四种:十进制、二进制、十六进制、八进制。
对于数值字面量,主要使用不同的前缀来区分:
- 十进制:取值数字 0-9;不用前缀。
- 二进制(Binary): 取值数字 0 和 1 ;前缀 0b 或 0B。
- 十六进制(Hexadecimal):取值数字 0-9 和 a-f ;前缀 0x 或 0X。
- 八进制(Octal):取值数字 0-7 ;前缀 0o 或 0O (ES6规定)。
位运算符
什么是位运算符?
位运算符指的是二进制位的运算,先将十进制数转成二进制后再进行运算。 在二进制位运算中,1表示true,0表示false。
JavaScript 中的按位操作符有:
运算符 | 用法 | 描述 |
---|---|---|
按位与(AND) | A & B | 如果对应的二进制位都为 1,则该二进制位为 1 |
按位或(OR) | A | B | 如果对应的二进制位有一个为 1,则该二进制位为 1 |
按位异或(XOR) | A ^ B | 如果对应的二进制位只有一个为 1,则该二进制位为 1 |
按位非(NOT) | ~A | 反转所有二进制位,即 1 转换为 0,0 转换为 1 |
按位左移 | A << B | 将所有二进制位统一向左移动指定的位数,并在最右侧补 0 |
按位右移 | A >> B | 按位右移(有符号右移):将所有二进制位统一向右移动指定的位数,并拷贝最左侧的位来填充左侧 |
无符号右移 | A >>> B | 按位右移零(无符号右移):将所有二进制位统一向右移动指定的位数,并在最左侧补 0 |
示例
1 | const A = 0101,B = 0001 |
位运算符在工作中的应用得比较少,但有时候它可以很巧妙地解决我们工作中一些问题。
运用场景
在传统的权限系统中,不同的权限之间存在很多关联关系,而且有很多种权限组合方式,在这种情况下,权限就越难以维护。这种情况我们就可以使用位运算符,可以很巧妙地解决这个问题。
假设我们现在权限系统中有4种基本权限:可读、可写、创建、删除。
那么我们可以定义4个二进制变量表示:
1 | // 所有权限码的二进制数形式,有且只有一位值为 1,其余全部为 0 |
权限操作
使用 按位或(OR) 添加权限:
1
2
3
4
5
6
7
8
9
10// 赋予用户全部权限
const ALL = READ | WRITE | CREATE | DELETE
console.log(ALL)
// 结果位 1111,每个位置的1就代表拥有这个权限,这里全部是1,就代表拥有全部权限。
// 同样的,这些权限可以自由组合
const READ_AND_WRITE = READ | WRITE // 可读和可写,结果为 1100
const READ_AND_CREATE = READ | CREATE // 可读和创建,结果为 1010
const WRITE_AND_DELETE = WRITE | DELETE // 可写和删除,结果为 0101使用 按位与(AND) 校验权限:
1
2
3
4
5
6
7
8
9
10// 比如我们拿到一个用户的权限,我们怎么根据返回的数据判断是否拥有某个权限呢?
// 假设现在返回了 拥有可读可写的权限组合:1100
const auth = READ | WRITE // 可读和可写,结果为 1100
// 判断是否包含 READ 权限
const isRead = (auth & READ) === READ // true
// 是否包含 DELETE 权限
const isDelete = (auth & DELETE) === DELETE // false使用 按位非(NOT) 剔除权限:
1
2
3
4
5
6
7// 全部权限
const ALL = READ | WRITE | CREATE | DELETE
// 如果要剔除 WRITE 权限,应该怎么做呢,先执行 ~ 取反,再执行 & 运算
const notWrite = ALL & ~WRITE // 输出 1011
// 剔除 DELETE 权限
const notDelete = ALL & ~DELETE // 输出 1110
局限性
本文提到的这种位运算符方案,有一定的前提条件:
- 每种权限码都是唯一的,有且只有一位值为 1。
- 一个数字的范围只能在 -(2^53 -1) 和 2^53 -1 之间,如果权限系统设计得比较庞大,这种方式可能不合适。
不过总的来说,这种方式在中小型业务中应该够用了。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 白雾茫茫丶!
评论
您无需删除空行,直接评论以获取最佳展示效果