GO 权限管理之 Casbin
GO 权限管理之 Casbin
我们来回顾一下上次分享的 GO中 gjson
库的应用和分享,它主要是提供了一种非常快速且简单的方式从json
文档中获取相应值
- 分享了
json
与gjson
分别代表什么 gjson
的简单使用gjson
校验,获取值gjson
的json 行
gjson
的键路径匹配规则gjson
的修饰符和自定义修饰符
gjson
还有点兴趣的话,可以查看文章 GO中gjson的应用和分享文章图片
今天咱们来分享一下 GO里面的权限管理,
Casbin
权限管理是什么?
一般指根据系统设置的安全规则或者安全策略我们可能会把
用户可以访问而且只能访问自己被授权的资源,不多不少刚刚好
权限管理几乎出现在任何系统里面
用户身份认证
、 密码加密
、 系统管理
与权限管理弄混淆,那么他们具体的侧重点是什么呢?- 用户身份认证
用户身份认证指的是通过某种凭证来证明自己的身份,例如账号密码,指纹,人脸识别等等
- 系统管理
- 密码加密
文章图片
Casbin 是个啥? 是 GO 项目的功能强大且高效的开源访问控制库,
casbin
支持常用的多种访问控制模型,例如:RBAC
ABAC
ACL
casbin
来做权限管理有一个比较好的地方是,casbin
是支持多种语言的,就像protobuf一样也是支持多种语言咱们来看看 Casbin 有啥特性
- 实施策略是这样子的
{subject, object, action}
,
- 他可以处理访问控制模型以及其存储对应的策略
- 在
RBAC
中的角色层次结构 中,他可以管理角色用户映射和角色角色映射 - 他支持内置的超级用户
root
或administrator
- 支持多个内置运算符规则匹配
hello/world
,就可以将其映射到 hello*模式
- 不支持身份验证
- 不支持管理用户或角色列表
Casbin
的基本模型
【GO 权限管理之 Casbin】在 Casbin
库中,他是基于PERM
元模型将访问控制模型抽象为CONF文件,有如下4个部分- 策略
- 效果
- 请求
- 匹配器
ACL
的CONF
模型#请求定义
[request_definition]
r = sub, obj, act
#策略定义
[policy_definition]
p = sub, obj, act
#角色定义
[role_definition]
g = _, _[policy_effect]
e = some(where (p.eft == allow))[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
例如一个
ACL
模型的示例策略p, xiaomt, data1, read
p, xiaomt, data2, write
咱们来写一个DEMO
main.go
文件写gin
对应的接口以及casbin
的使用rbac_models.conf
RBAC CONF文件
文章图片
咱们写一个路由,里面添加一个拦截器,再写一个接口
/api/v1/hello
,使用GET方法验证效果package mainimport (
"fmt"
"log""github.com/casbin/casbin"
xd "github.com/casbin/xorm-adapter"
"github.com/gin-gonic/gin"
_ "github.com/go-sql-driver/mysql"
)// myAuth 拦截器
func myAuth(e *casbin.Enforcer) gin.HandlerFunc {
return func(c *gin.Context) {
obj := c.Request.URL.RequestURI()
// 获取方法
act := c.Request.Method
sub := "root"// 判断策略是否已经存在了
if ok := e.Enforce(sub, obj, act);
ok {
log.Println("Check successfully")
c.Next()
} else {
log.Println("sorry , Check failed")
c.Abort()
}
}
}func main() {
// 使用自己定义rbac_db
// 最后的一个参数咱们写true ,否则默认为false,使用缺省的数据库名casbin,不存在则创建
a := xd.NewAdapter("mysql", "root:123456@tcp(127.0.0.1:3306)/mycasbin?charset=utf8", true)e := casbin.NewEnforcer("./rbac_models.conf", a)//从DB中 load 策略
e.LoadPolicy()//new 一个路由
r := gin.New()r.POST("/api/v1/add", func(c *gin.Context) {
log.Println("add a policy")
if ok := e.AddPolicy("root", "/api/v1/hello", "GET");
!ok {
log.Println("The strategy already exists")
} else {
log.Println("add successfully ...")
}
})//使用自定义拦截器中间件,每一个接口的访问,都会通过这个拦截器
r.Use(myAuth(e))
//创建请求
r.GET("/api/v1/hello", func(c *gin.Context) {
fmt.Println("hello wolrd")
})// 监听 127。0.0.1:8888
r.Run(":8888")
}
对于上述
xd.NewAdapter
读取数据的操作,咱们可以看看具体实现文章图片
具体源码在
"github.com/casbin/xorm-adapter"
中的 adapter.go
// NewAdapter is the constructor for Adapter.
// dbSpecified is an optional bool parameter. The default value is false.
// It's up to whether you have specified an existing DB in dataSourceName.
// If dbSpecified == true, you need to make sure the DB in dataSourceName exists.
// If dbSpecified == false, the adapter will automatically create a DB named "casbin".
func NewAdapter(driverName string, dataSourceName string, dbSpecified ...bool) *Adapter {
a := &Adapter{}
a.driverName = driverName
a.dataSourceName = dataSourceNameif len(dbSpecified) == 0 {
a.dbSpecified = false
} else if len(dbSpecified) == 1 {
a.dbSpecified = dbSpecified[0]
} else {
panic(errors.New("invalid parameter: dbSpecified"))
}// Open the DB, create it if not existed.
a.open()// Call the destructor when the object is released.
runtime.SetFinalizer(a, finalizer)return a
}
再来看看
casbin.NewEnforcer
源码文件在
"github.com/casbin/casbin"
中 enforcer.go
NewEnforcer
通过文件或 DB 创建一个 enforcer
, 如下是官方的案例写法,注意如下案例// e := casbin.NewEnforcer("path/to/basic_model.conf", "path/to/basic_policy.csv")
// MySQL DB:
// a := mysqladapter.NewDBAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")
// e := casbin.NewEnforcer("path/to/basic_model.conf", a)
func NewEnforcer(params ...interface{}) *Enforcer {
e := &Enforcer{}parsedParamLen := 0
// 判断参数个数
if len(params) >= 1 {
enableLog, ok := params[len(params)-1].(bool)
if ok {
e.EnableLog(enableLog)parsedParamLen++
}
}
// 省略 部分代码
return e
}
上述代码,大家感兴趣的话,可以将代码贴到自己的环境中
使用类似
postman
工具来访问接口,查看效果哦,需要配置好mysql
数据库文章图片
对于上述的
gin
和拦截器
若感兴趣的话, 可以查看文章- 分享一波gin的路由算法
- 瞧一瞧 gRPC的拦截器
- Gin实战演练
- 分享了权限管理是什么
- Casbin 是什么
- Casbin 的特性
- Casbin 的应用案例
文章图片
好了,本次就到这里,下一次 工作中后端是如何将API提供出去的?swaggo很不错
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是小魔童哪吒,欢迎点赞关注收藏,下次见~
推荐阅读
- PMSJ寻平面设计师之现代(Hyundai)
- 太平之莲
- 闲杂“细雨”
- 七年之痒之后
- 深入理解Go之generate
- 由浅入深理解AOP
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 生活随笔|好天气下的意外之喜
- 感恩之旅第75天