gin集成casbin

2,428 阅读2分钟

介绍

权限管理在几乎每个系统中都是必备的模块。如果项目开发每次都要实现一次权限管理,无疑会浪费开发时间,增加开发成本。因此,casbin库出现了。casbin是一个强大、高效的访问控制库。支持常用的多种访问控制模型,如ACL/RBAC/ABAC等。可以实现灵活的访问权限控制。同时,casbin支持多种编程语言,Go/Java/Node/PHP/Python/.NET/Rust。我们只需要一次学习,多处运用

特征

  • 以经典{subject, object, action}形式或您定义的自定义形式实施策略,同时支持允许和拒绝授权。
  • 处理访问控制模型及其策略的存储。
  • 管理角色用户映射和角色角色映射(RBAC中的角色层次结构)。
  • 支持内置的超级用户,例如root或administrator。超级用户可以在没有显式权限的情况下执行任何操作。
  • 多个内置运算符支持规则匹配。例如,keyMatch可以将资源键映射/foo/bar到模式/foo*

Casbin不执行的操作:

  • 身份验证(又名验证username以及password用户登录时)
  • 管理用户或角色列表。我相信项目本身管理这些实体会更方便。用户通常具有其密码,而Casbin并非设计为密码容器。但是,Casbin存储RBAC方案的用户角色映射。

gin集成casbin

第一步:编写conf文件

在项目根目录下增加rbac_model.conf文件

采用的是Casbin中最基本,最简单的模型是ACL

[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 = r.sub == p.sub && keyMatch2(r.obj,p.obj) && r.act == p.act

第二步:安装依赖包

go get github.com/casbin/casbin/v2
go get github.com/casbin/gorm-adapter/v3 //这里采用的是gorm,可根据自已业务更换

第三步:编写casbin帮助类

package system

import (
	"github.com/casbin/casbin/v2"
	gormadapter "github.com/casbin/gorm-adapter/v3"
	"sync"
	"wsn-gin/global"
)

type CasbinService struct {
}

var CasbinServiceApp = new(CasbinService)

//持久化到数据库
var (
	syncedEnforcer *casbin.SyncedEnforcer
	once           sync.Once
)

func (c *CasbinService) Casbin() *casbin.SyncedEnforcer {
	once.Do(func() {
		a, _ := gormadapter.NewAdapterByDB(global.GVA_DB)
		syncedEnforcer, _ = casbin.NewSyncedEnforcer(global.GVA_CONFIG.Casbin.ModelPath, a)
	})
	_ = syncedEnforcer.LoadPolicy()
	return syncedEnforcer
}

global.GVA_DB为gorm对象,传入之后,会自动在数据库中生成casbin_rule表

image.png

第四步:编写gin中间件


func CasbinHandler() gin.HandlerFunc {
   return func(c *gin.Context) {
      //获取请求path
      obj := c.Request.URL.Path
      //获取请求方法
      act := c.Request.Method
      //角色应该从token解析出来,此处为了节约时间,写死了值
      sub := "admin"
      //引入casbin
      e := casbinService.Casbin()

      //新增几个策略
      //e.AddPolicy("admin", "/v1/customer/customer", "GET")
      ////删除策略
      //e.RemovePolicy("admin", "/api/v1/hello", "GET")
        ////获取策略
      //list := e.GetPolicy()
      //for _, vlist := range list {
      // for _, v := range vlist {
      //    fmt.Printf("value: %s, ", v)
      // }
      //}

      //判断策略是否存在
      success, _ := e.Enforce(sub, obj, act)
      //如果环境变量是开发者模式或者casbin校验通过
      if global.GVA_CONFIG.System.Env == "develop" || success {
         c.Next()
      } else {
         response.FailWithDetailed(gin.H{}, "权限不足", c)
         c.Abort()
         return
      }
   }
}

可以手动在数据库增加一些策略,或者通过上述e.AddPolicy()方法增加策略。

如果环境变量是本地模式,则可跳过此中间件。

新增策略之后,数据库如下:

image.png

第五步:引入中间件

注意中间件引入顺序,应该先域名,再jwt校验,再casbin校验。

这里为了测试方便,casbin放在了jwt前面。 image.png