实际项目中肯定要用rbac这种权限模型,因此model使用如下
rbac_model.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]
# 当访问实体为root时直接认证通过,项目肯定需要特殊权限用户
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act || r.sub == "root"
由于casbin、gorm都有不同版本,因此引用的包一定要对上!!!
casbin.go
import (
"github.com/casbin/casbin/v2"
gormadapter "github.com/casbin/gorm-adapter/v3"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
const (
// 刚才的rbac配置文件路径
configName = "./configs/rbac_model.conf"
)
var (
enforcer *casbin.Enforcer
errErrorPermission = errors.New("权限有误")
)
func InitCasbin() {
// 这里填入自己的"gorm.io/gorm"的db链接,而不是jinzhu/gorm的,会对不上
adapter, err := gormadapter.NewAdapterByDB(*gorm.DB)
if err != nil {
panic(err)
}
enforcer, err = casbin.NewEnforcer(configName, adapter)
if err != nil {
panic(err)
}
enforcer.EnableLog(false)
err = enforcer.LoadPolicy()
if err != nil {
panic(err)
}
}
casbin启动默认会在数据库下新建一张casbin_rule表,如果创建有问题,可能是默认引擎是MyISAM,而需要用InnoDB,可以显示的AutoMigrate
db.Set("gorm:table_options", "ENGINE=InnoDB;CHARSET=utf8mb4").AutoMigrate(&gormadapter.CasbinRule{})
在casbin_rule表中可以定义某些用户加入组,然后以“组”概念去匹配权限,但是这样你的user_message表跟user_role表等于直接用casbin_rule里的定义了,或者需要做关联关系,后面新增用户加权限等等是在操作casbin_rule表的。实际情况下不合理,因此还是自己定义好user_message表跟user_role表,并维护好这两个表多对多关系即可,而casbin的实体验证直接验证“权限”这个概念即可,因此casbin_rule表仅需要保留Policie信息即可
casbin_rule表
# 注意get要小写!
INSERT INTO `casbin_rule` (`ptype`,`v0`,`v1`,`v2`) VALUES ('p','dev','/api/dev/*','get');
casbin.go
func CasbinMiddleWare() func(c *gin.Context) {
return func(c *gin.Context) {
// 白名单下url不验证
for _, whiteUrl := range whiteList {
if strings.Contains(c.Request.URL.String(), whiteUrl) {
c.Next()
return
}
}
username := c.GetString("username")
// 换成自己的角色权限字段
iuserRoles, exists := c.Get("userRoles")
zap.L().Debug("c.Get", zap.String("username", username), zap.Any("iuserRoles", iuserRoles))
if username == "" || !exists {
handlerbase.BuildErrorNilResponse(c, errErrorAuth)
c.Abort()
return
}
p := c.Request.URL.Path
m := c.Request.Method
zap.L().Debug("Request", zap.String("p", p), zap.String("m", m))
userRoles := iuserRoles.([]model.UserRole)
for _, userRole := range userRoles {
// 如果不使用strings.ToLower则casbin_rule表中act需要为大写!
// act实体验证该权限名称!
hit, err := enforcer.Enforce(userRole.RoleName, p, strings.ToLower(m))
if err != nil || !hit {
continue
} else {
c.Next()
return
}
}
handlerbase.BuildErrorNilResponse(c, errErrorPermission)
c.Abort()
}
}
标签:err,casbin,rule,act,gin,gorm,zap
From: https://www.cnblogs.com/bfmq/p/17494295.html