用户组权限控制如何避免重复权限导致混乱?
我现在在做用户权限控制,用用户组来管理权限,但发现不同用户组可能会有重复的权限项。比如用户同时属于管理员组和编辑组,两个组都有”delete_post”权限,合并权限时该怎么处理才不会重复?
我尝试用数组存储权限,用Set去重后转回数组,但发现当权限需要叠加时,重复项还是会导致判断逻辑混乱。比如前端用includes(‘delete_post’)就会被多次触发,这样写法有问题吗?
const groups = [
{ id:1, name:'管理员', perms:['delete_post', 'edit_user'] },
{ id:2, name:'编辑组', perms:['publish_post', 'delete_post'] }
];
const userPerms = groups.flatMap(g => g.perms); // 这里会有重复的'delete_post'
用 Set 是对的,但你最后又转回数组去做 includes 判断,这一步其实可以反过来做:先收集所有权限存进 Set,判断的时候直接用 Set.has() 就行了,不需要数组 includes。这样不仅避免重复,还能提升判断性能。
更好的写法是:
const permsSet = new Set(groups.flatMap(g => g.perms));
console.log(permsSet.has('delete_post')); // 判断有没有权限就这一句
如果你后面确实需要数组形式,再用 Array.from(permsSet) 转回来。但判断权限这种高频操作,原生 Set 的 has 方法比数组的 includes 快得多,而且语义也更清晰。
你原来写法的问题就在于:保留了重复的数组,然后用 includes 判断,这样虽然结果没错,但逻辑上是「我有没有看到这个权限」而不是「我到底有没有这个权限」。换成 Set 之后逻辑就清晰多了,代码也更干净。
如果你后面还要处理权限优先级(比如某些组权限更高),那就不能只靠 Set 了,得按优先级排序后再合并。不过根据你现在的描述,先用 Set 去重已经够用了。
Set来去重,然后再转回数组,这样能保证权限列表里不会有重复项。具体实现可以这样:
这样处理后,
userPerms就是一个干净的、没有重复的权限列表了。前端用includes('delete_post')判断时就不用担心会被多次触发。另外提醒一下,如果你的权限系统比较复杂,建议在后端也做类似的去重处理,前后端一起保障权限的准确性。毕竟权限这事,宁可麻烦点,也不能出错,不然用户该删的东西删不了,不该删的倒删了,那就尴尬了。