【笔记】Go语言通过Casbin和Gorm管理权限

前言

Go语言通过Casbin管理权限,并通过Gorm在Mysql中存储权限规则

下载依赖

Casbin依赖

1
2
go get github.com/casbin/casbin/v2
go get github.com/casbin/gorm-adapter/v3

Gorm依赖

1
2
go get gorm.io/gorm
go get gorm.io/driver/mysql

定义模型配置

model.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[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

创建适配器对象

创建新的Gorm对象

  • 连接Mysql,创建适配器对象
  • 如果数据库不存在或数据表casbin_rule不存在,则会自动创建

<username>:用户名
<password>:密码
<host>:IP地址或域名
<port>:端口号
<database>:数据库名

1
adapter, err := gormadapter.NewAdapter("mysql", "<username>:<password>@tcp(<host>:<port>)/<database>", true)

使用已经创建的Gorm对象

<db>:Gorm对象

1
adapter, err := gormadapter.NewAdapterByDB(<db>)

手动指定数据表名

  • 手动指定数据表名,而不是使用默认的casbin_rule数据表

<table_name>:数据表名

1
adapter, err := gormadapter.NewAdapterByDBWithCustomTable(<db>, nil, "<table_name>")

创建执法者对象

  • 通过模型配置文件和适配器对象创建执法者对象

./model.conf:定义模型配置

1
enforcer, err := casbin.NewEnforcer("./model.conf", adapter)

从数据库加载规则

1
err := enforcer.LoadPolicy()

保存规则到数据库

1
err := enforcer.SavePolicy()

规则增删改

添加规则

1
exist, err := enforcer.AddPolicy("用户名或组名", "接口名", "请求类型")

删除规则

1
ok, err := enforcer.RemovePolicy("用户名或组名", "接口名", "请求类型")

根据过滤条件批量删除规则

根据用户名或组名批量删除规则
1
ok, err := enforcer.RemoveFilteredPolicy(0, "用户名或组名")
根据接口名批量删除规则
1
ok, err := enforcer.RemoveFilteredPolicy(0, "", "接口名")
1
ok, err := enforcer.RemoveFilteredPolicy(1, "接口名")

组增删改

向组中新增用户

1
exist, err := enforcer.AddRoleForUser("用户名", "组名")

从组中删除用户

1
ok, err := enforcer.DeleteRoleForUser("用户名", "组名")

校验规则

  • 返回规则判定结果布尔值
1
allow, err := enforcer.Enforce("用户名或组名", "接口名", "请求类型")

自定义函数

超级管理员判定

  • 在模型中添加规则
model.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[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 || checkRoot(r.sub)
  • 自定义超级管理员判定规则
1
2
3
4
5
6
7
// 自定义超级管理员判定规则
enforcer.AddFunction("checkRoot", func(arguments ...interface{}) (interface{}, error) {
// 获取第一个参数
sub := arguments[0].(string)
// 检查用户的是否为在root组
return enforcer.HasRoleForUser(sub, "root")
})
  • 将用户添加到root组
1
ok, err := enforcer.DeleteRoleForUser("用户名", "root")

完成

参考文献

知乎——孤雨
CSDN——LeoForBest
casbin/gorm-adapter
CSDN——Dreamy_Lois