用set实现权限白名单过滤的核心是交集运算:先合并用户多源权限,再与白名单求交集得合法权限;并集仅用于合并权限源且须在过滤前,差集用于越权审计。

用 Set 实现权限白名单过滤,核心是把“用户实际拥有的权限”和“系统允许的白名单权限”都转为 Set,再通过集合运算快速裁剪出合法权限。关键不在语法多炫,而在明确每次运算的业务含义。
并集:合并多来源权限(慎用)
并集(new Set([...a, ...b]) 或 Set.prototype.union)适合整合不同渠道授予的权限,比如角色权限 + 临时授权 + 部门继承权限。但白名单场景中,并集不能用于“放行”,它只会扩大权限范围,可能突破白名单边界。
- 仅在构建最终“用户全量权限集”阶段使用,且必须放在白名单过滤之前
- 白名单本身不参与并集——它是过滤器,不是权限源
- 示例:用户角色权限
['read', 'edit'],临时加授['delete']→ 合并得['read','edit','delete'],后续再拿这个结果去和白名单求交集
交集:白名单过滤的核心操作
交集即保留“用户有 + 系统允许”的权限,天然对应白名单语义。JavaScript 原生无直接交集方法,需手动实现:
function intersection(setA, setB) {
return new Set([...setA].filter(x => setB.has(x)));
}
- 输入:用户权限 Set(如
new Set(['read','export','admin']))、白名单 Set(如new Set(['read','write','export'])) - 输出:
Set {'read','export'}—— 既被用户持有、又在白名单中的权限 - 这是最常用、最安全的白名单执行方式,推荐封装为
filterByWhitelist(userPerms, whitelist)
差集:识别越权项或生成禁用清单
差集([...userPerms].filter(x => !whitelist.has(x)))不用于放行,而用于审计与拦截:
- 检查用户是否申请了白名单外权限:差集非空 → 存在越权,可记录日志或拒绝请求
- 生成“禁止权限列表”供前端灰显按钮:如白名单为
['read'],用户权限含['read','edit','delete'],差集['edit','delete']即应禁用项 - 注意:差集顺序依赖用户权限遍历顺序,无需排序,仅作存在性判断
实战建议:组合使用 + 避坑
典型流程是:合并权限 → 交集过滤 → (可选)差集审计。避免常见错误:
- 别把白名单当角色权限用:白名单是系统级约束,不是某角色的权限声明
- 权限字符串保持统一格式:大小写、下划线/短横线要一致,否则
'Read'和'read'被视为不同项 - Set 初始化时去重:用户权限数组若含重复项(如后端误传),Set 自动去重,反而是优势
- 高频调用场景可缓存白名单 Set:白名单通常全局固定,不必每次新建











