1、权限管理
简易版
import (
"log"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
gormadapter "github.com/casbin/gorm-adapter/v3"
_ "github.com/go-sql-driver/mysql"
)
// 初始化适配器
func casbinInit() {
// 使用gorm适配器
a, _ := gormadapter.NewAdapterByDBUseTableName(global.Orm, "", "casbin_rule_test")
m, err := model.NewModelFromString(`
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
`)
if err != nil {
log.Fatalf("error: model: %s", err)
}
e, err := casbin.NewEnforcer(m, a)
if err != nil {
log.Fatalf("error: enforcer: %s", err)
}
}
// VerifyPermission 验证用户权限
// sub 想要访问资源的用户
// obj 将要被访问的资源
// act 用户对资源实施的操作
func VerifyPermission(sub, obj, act string) bool {
ok, err := e.Enforce(sub, obj, act)
if err != nil {
// 处理错误
}
if ok == true {
// 允许 alice 读取 data1
} else {
// 拒绝请求,抛出异常
}
return false
}
详细版:一、api管理
存储所有的api信息
结构
type SysApi struct {
gorm.Model
Path string `json:"path" gorm:"comment:api路径"` // api路径
Description string `json:"description" gorm:"comment:api中文描述"` // api中文描述
ApiGroup string `json:"apiGroup" gorm:"comment:api组"` // api组
Method string `json:"method" gorm:"default:POST;comment:方法"` // 方法:创建POST(默认)|查看GET|更新PUT|删除DELETE
}
给用户角色绑定api
func (casbinService *CasbinService) UpdateCasbin(AuthorityID uint, casbinInfos []request.CasbinInfo) error {
authorityId := strconv.Itoa(int(AuthorityID))
casbinService.ClearCasbin(0, authorityId)
rules := [][]string{}
for _, v := range casbinInfos {
rules = append(rules, []string{authorityId, v.Path, v.Method})
}
e := casbinService.Casbin()
success, _ := e.AddPolicies(rules)
if !success {
return errors.New("存在相同api,添加失败,请联系管理员")
}
err := e.InvalidateCache()
if err != nil {
return err
}
return nil
}
casbinService.Casbin()为
func (casbinService *CasbinService) Casbin() *casbin.CachedEnforcer {
once.Do(func() {
a, err := gormadapter.NewAdapterByDB(global.GVA_DB)
if err != nil {
zap.L().Error("适配数据库失败请检查casbin表是否为InnoDB引擎!", zap.Error(err))
return
}
text := `
[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
`
m, err := model.NewModelFromString(text)
if err != nil {
zap.L().Error("字符串加载模型失败!", zap.Error(err))
return
}
cachedEnforcer, _ = casbin.NewCachedEnforcer(m, a)
cachedEnforcer.SetExpireTime(60 * 60)
_ = cachedEnforcer.LoadPolicy()
})
return cachedEnforcer
}
通过角色id获取api权限
func (casbinService *CasbinService) GetPolicyPathByAuthorityId(AuthorityID uint) (pathMaps []request.CasbinInfo) {
e := casbinService.Casbin()
authorityId := strconv.Itoa(int(AuthorityID))
list := e.GetFilteredPolicy(0, authorityId)
for _, v := range list {
pathMaps = append(pathMaps, request.CasbinInfo{
Path: v[1],
Method: v[2],
})
}
return pathMaps
}
api权限校验代码(中间件)
// 从context获取信息
waitUse, _ := utils.GetClaims(c)
//获取请求的PATH
path := c.Request.URL.Path
obj := strings.TrimPrefix(path, global.GVA_CONFIG.System.RouterPrefix)
// 获取请求方法
act := c.Request.Method
// 获取用户的角色
sub := strconv.Itoa(int(waitUse.AuthorityId))
e := casbinService.Casbin() // 判断策略中是否存在
success, _ := e.Enforce(sub, obj, act)
if !success {
fmt.Println("权限不足")
return
}
二、菜单管理
不同的角色对应不同的菜单权限
type SysMenu struct {
SysBaseMenu
MenuId string `json:"menuId" gorm:"comment:菜单ID"`
AuthorityId uint `json:"-" gorm:"comment:角色ID"`
Children []SysMenu `json:"children" gorm:"-"`
Parameters []SysBaseMenuParameter `json:"parameters" gorm:"foreignKey:SysBaseMenuID;references:MenuId"`
Btns map[string]uint `json:"btns" gorm:"-"`
}
type SysAuthorityMenu struct {
MenuId string `json:"menuId" gorm:"comment:菜单ID;column:sys_base_menu_id"`
AuthorityId string `json:"-" gorm:"comment:角色ID;column:sys_authority_authority_id"`
}
SysAuthorityMenu 表,通过角色id可查询所有menuid
三、角色管理
存储所有角色信息
type SysAuthority struct {
CreatedAt time.Time // 创建时间
UpdatedAt time.Time // 更新时间
DeletedAt *time.Time `sql:"index"`
AuthorityId uint `json:"authorityId" gorm:"not null;unique;primary_key;comment:角色ID;size:90"` // 角色ID
AuthorityName string `json:"authorityName" gorm:"comment:角色名"` // 角色名
ParentId *uint `json:"parentId" gorm:"comment:父角色ID"` // 父角色ID
DataAuthorityId []*SysAuthority `json:"dataAuthorityId" gorm:"many2many:sys_data_authority_id;"`
Children []SysAuthority `json:"children" gorm:"-"`
SysBaseMenus []SysBaseMenu `json:"menus" gorm:"many2many:sys_authority_menus;"`
Users []SysUser `json:"-" gorm:"many2many:sys_user_authority;"`
DefaultRouter string `json:"defaultRouter" gorm:"comment:默认菜单;default:dashboard"` // 默认菜单(默认dashboard)
}