要解决的需求
背景:
- 权限控制是企业平台必不可少的功能模块之一,小到二十人的团队,权限管理都是必要的,从根本上减少每个人误操作的可能性。权限管理一般分“认证”和“授权”两大块,前者表示确定你是谁,后者确定你能做什么。本系统主要解决第二个问题。
- 最简单的一些权限系统实现,有着诸多缺点,诸如前端直接通过后端数据限制、后端再单独check,有着不够安全、不同平台难以兼容、代码分别手动插入增加心智成本、难以记录日志等缺点。
一般要控制权限的资源:
- 前端路由和其他具体控件
- 后端接口
Casbin 框架引入
怎么实现这样一个复杂的权限管理需求呢?难点在哪里?
权限管理这件事情,最简单的案例就是:
- 配置策略,允许 user1 访问 A 资源
- user1 想要访问 B 资源
- 没有匹配到策略拒绝访问
但是我们要实现的需求往往没有这么简单
- rbac,基于角色的权限控制会比较常用。我们一般不进行用户这样细粒度的权限控制,会让用户分角色,来做基于角色来做高效范围控制
- abac,能够获取操作创建人、限制发布时间等基于数据的操作
,一种成熟的方案就使用 Casbin 框架
他是一个权限管理框架,可以通过预先设置的 请求类型 request、权限策略 policy 来实现具体的权限控制
使用框架的步骤,就是定义模型 -> 创建策略 -> 代码使用
这个就是他的核心,可以参考 casbin.org/editor
模型里其他值得一提的另外两项是 权限效果 effect 和匹配器 matcher:
- 效果是一个布尔表达式,意味着多个策略匹配的时候,如何决定是否通行。这个说简单点,其实就是用一些常见策略。一个过就行,一个拒绝就拒绝,一个过且不能有拒绝的策略等等。
- 匹配器是定义请求过来了怎么样才算匹配一个策略。最简单的形式就是sub主语,act行为,obj被访问的对象三个全部相等就是匹配了。但是我们也有一些常见的其他需求,像是rbac,接口路径匹配,或者是我们需要做更详细的,比如说控制时间等因素。
实现大致分析
实现组件
- 业务前端
- 存储用户信息的后端
- 封装权限验证的 SDK
后端需要的东西
- 每个用户、他们的角色(角色如果有更详细的信息,或者有特殊角色需求再按需扩展表)
- 策略存储、模型的定义
SDK需要的东西
- httpgetter
- dbadpater
- 封装一下验证的逻辑、中间件等
可能存在的实现难点(难点其实都是对 Casbin 的特化使用上了)
- 如果我们需要从多种角度去实现角色控制需求,比方说有些地方我们会按照开发层面的角色(qa开发产品等)来控制,另一些地方又需要按部门,或者还有一些地方可能设置超级管理员。这种情况要怎么设计呢?方法之一是,我们把模型里面的 sub 用一种字符串规则来组合成不同规则(类似于redis_key)的设置,比方说对于不同的身份,我们而可以
Role:{userId}Superuser:{userId}Dept:{Dept}id,然后最终匹配不同的 Casbin模型策略。 - 如何携带操作时间、具体操作内容等数据?定义好 model request 就好了,最后按字符串传入再特化处理。