学习了之前的Casbin-model,就可以开始书写casbin的具体实现代码了,非常惭愧,昨天没有搓出博客,太懒了
思路 在我认知范围内,casbin的具体实现思路是
casbin 和 gorm.adapter的依赖下载后
准备 model 和 adapter
通过上面两个东西创建一个enforce
提前加入 role+data1+action
其他需要做的就是 添加项目时 将 user与role绑定
requre user 访问是否有相应的role policy
添加一些其他的有关policy的函数,查看,删除啥的
实践 具体代码的呈现肯定不是直接按思路来的,不过我这里就按思路呈现一下代码。
准备 model 和 adapter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const ( casModel = ` [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 ` ) m, err := model.NewModelFromString(casModel) adapter, _ := gormadapter.NewAdapter("mysql" , "user:password@tcp(127.0.0.1:3307)/mysql" , true )
官方文档里model还有两种写法:
1 2 e := casbin.NewEnforcer("examples/rbac_model.conf" , "examples/rbac_policy.csv" )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 m := model.NewModel() m.AddDef("r" , "r" , "sub, obj, act" ) m.AddDef("p" , "p" , "sub, obj, act" ) m.AddDef("g" , "g" , "_, _" ) m.AddDef("e" , "e" , "some(where (p.eft == allow))" ) m.AddDef("m" , "m" , "g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act" ) a := fileadapter.NewAdapter("examples/rbac_policy.csv" ) e := casbin.NewEnforcer(m, a)
通过上面两个东西创建一个enforce
1 2 e, err := casbin.NewEnforcer(m, adapter)
提前加入 role+data1+action
1 2 3 4 5 func (e *MyEnforce) AddBasedPolicies() { e.AddPolicy("user" , "users" , "read" ) e.AddPolicy("user" , "users" , "write" ) }
其他需要做的就是 添加项目时 将 user与role绑定
1 func (e *MyEnforce) LinkUserWithPolicy(name string )
requre user 访问是否有相应的role policy
1 2 3 4 5 func (e *MyEnforce) CheckUserPolicyForRead(name, data, action string ) bool { ok, _ := Enforce.Enforce(name, data, action) return ok }
添加一些其他的有关policy的函数,查看,删除啥的
1 2 3 4 5 func (e *MyEnforce) UnLinkUserWithPolicy(name string ) error { _, err := e.RemoveGroupingPolicy(name, "user" ) return err }
整体代码呈现 1 2 3 4 5 6 7 8 9 type MyEnforce struct { *casbin.Enforcer } func GetEnforce () *MyEnforce { return Enforce }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 const ( casModel = ` [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 ` ) var Enforce *MyEnforcefunc Init () { var err error Enforce, err = createEnforcer() if err != nil { log.SugarLogger.Error(err) return } err1 := Enforce.LoadPolicy() if err1 != nil { log.SugarLogger.Error(err) return } Enforce.EnableAutoSave(true ) Enforce.AddBasedPolicies() } func createEnforcer () (*MyEnforce, error ) { m, err := model.NewModelFromString(casModel) if err != nil { return nil , err } adapter, err := gormadapter.NewAdapter("mysql" , "user:password@tcp(127.0.0.1:3307)/mysql" , true ) if err != nil { return nil , err } e, err := casbin.NewEnforcer(m, adapter) if err != nil { return nil , err } return &MyEnforce{e}, nil }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package casbinfunc (e *MyEnforce) AddBasedPolicies() { e.AddPolicy("user" , "users" , "read" ) e.AddPolicy("user" , "users" , "write" ) } func (e *MyEnforce) LinkUserWithPolicy(name string ) error { _, err := e.AddGroupingPolicy(name, "user" ) return err } func (e *MyEnforce) UnLinkUserWithPolicy(name string ) error { _, err := e.RemoveGroupingPolicy(name, "user" ) return err } func (e *MyEnforce) CheckUserPolicyForRead(name, data, action string ) bool { ok, _ := Enforce.Enforce(name, data, action) return ok }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 func Register (c *gin.Context) { var user model.User if err := c.ShouldBindJSON(&user); err != nil { log.SugarLogger.Error(err) errs2.Fail(c, errs2.INVALID_REQUEST.WithOrigin(err)) return } if len (user.Name) == 0 || len (user.Password) == 0 || len (user.Email) == 0 { errs2.Fail(c, errs2.LOGIN_ERROR.WithTips("Username, password or email is required..." )) return } var v1 model.User result := db.DB.Where("name = ?" , user.Name).First(&v1) if result.Error == nil { errs2.Fail(c, errs2.LOGIN_ERROR.WithTips("姓名重复" )) } if err := db.DB.Create(&user).Error; err != nil { log.SugarLogger.Error(err) errs2.Fail(c, errs2.DB_CRUD_ERROR.WithOrigin(err)) return } err := casbin.Enforce.LinkUserWithPolicy(user.Name) if err != nil { log.SugarLogger.Error(err) errs2.Fail(c, errs2.SERVE_INTERNAL.WithOrigin(err)) return } errs2.Success(c, "注册成功" ) }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 func Delete (c *gin.Context) { password := c.PostForm("password" ) payload, exists := c.Get("Payload" ) if !exists { errs2.Fail(c, errs2.UNTHORIZATION.WithTips("没有获取到payload" )) return } load := payload.(*jwt.MyCustomClaims) ok := casbin.Enforce.CheckUserPolicyForRead(load.User, "users" , "write" ) if !ok { errs2.Fail(c, errs2.UNTHORIZATION.WithTips("没有权限修改" )) return } var user model.User db.DB.Where("name = ?" , load.User).First(&user) if user.Password != password { fmt.Println("user.Password" , user.Password) fmt.Println(password) errs2.Fail(c, errs2.INVALID_REQUEST.WithTips(password)) return } result := db.DB.Delete(&user) if result.Error != nil { log.SugarLogger.Error(result.Error) errs2.Fail(c, errs2.DB_CRUD_ERROR.WithOrigin(result.Error)) return } errs2.Success(c, "注销成功" ) }
1 2 3 4 5 6 7 8 9 10 11 func Init () { configs.Init() db.Init() casbin.Init() for _, m := range module.Modules { fmt.Println("Init Module: " + m.GetName()) m.Init() } }
总结 整体的代码实现参考了
官方文档
七淼up
老板的代码
总的来说,casbin就是一个工具,会用就行
如果不会用就找官网,官网的解释很详细,啥函数都一堆
casbin官网