用 Django 用的多了,再用其他语言或框架会有点吃力,因为 Django 是保姆级别的,基本上 Web 开发你能遇到的问题,都有现成的解决方案,拿来就用即可。比如说权限管理,甚至数据库里面的表都给你设计好了。如果没有 Django,比如说你用了 Flask,或者 FastAPI,那该怎么做权限管理?
你可能会说自己建立角色表、权限表,角色和权限的映射表,再为用户配置角色,为角色配置权限,最后在视图函数或拦截器上编写判断逻辑。
没错,基本是这样,但是实现起来非常麻烦,有没有比较简单又高效的方案呢?有,那就是 Casbin。
Casbin 是一个强大的、高效的开源访问控制框架,其权限管理机制支持多种访问控制模型。GitHub 有 11.1 k 的星。
Casbin 还是一个通用的框架,支持主流的编程语言:
Casbin 可以做:
Casbin 不能:
在 Casbin 中, 访问控制模型被抽象为基于 PERM (Policy, Effect, Request, Matcher) 的一个文件。因此,切换或升级项目的授权机制与修改配置一样简单。
举个例子吧,编写这样一个模型配置文件 model.conf:
# Request definition
[request_definition]
r = sub, obj, act
# Policy definition
[policy_definition]
p = sub, obj, act
# Policy effect
[policy_effect]
e = some(where (p.eft == allow))
# Matchers
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
你说 sub、obj、act 是啥?其实是抽象出来的东西,你可以这么理解:把 sub 当作用户角色,把 obj 当作资源对象,比如说 api 的路径,act 当作行为,比如说 get 或 post 请求。
这个模型配置文件就表示当请求的 sub,obj,act 等于策略中的 sub,obj,act 的时候就放行,否则拒绝。
现在来编写策略文件:policy.csv
p, root, /api/users/confirm, GET
p, admin, /api/users/confirm, GET
这个策略就表示如果 sub 是 root 或者 admin 的时候,就可以对 /api/users/confirm 执行 GET 请求。
然后在请求拦截器加上这样的判断逻辑:
import casbin
e = casbin.Enforcer("path/to/model.conf", "path/to/policy.csv")
def 拦截器(*args **kwargs)
sub = "admin" # 这里写死,实际上从 request 对象获取用户角色
obj = "/api/users/confirm" # 实际上从 request 对象获取 URI
act = "GET" # 实际上从 request 对象中获取请求方法
if e.enforce(sub, obj, act):
print("放行")
...
else:
print("拒绝")
...
就这,只需在拦截器加上一小段逻辑,对原有代码基本没有入侵,使用起来是不是非常简单?
策略的配置即可放在文件中,也可以放在数据库中,做到更为灵活的配置。
pip install casbin
casbin 还有很多高级的功能,这里说的只是最简单的一种,官方文档[1]也有非常丰富的例子:
我也正在学习 casbin,分享给需要的朋友们。如有问题,留言交流。
[1]官方文档: https://casbin.org/docs/zh-CN/get-started