gin+gorm角色权限管理

权限管理

权限比较少并且已确定的权限:

参考linux的读写执行权限,规定以二进制方式确定权限

const (
	ReadWeight = 1 << iota
	UpdateWeight
	WriteWeight
	DeleteWeight
)
func weightAuth(userWeight, targetWeight int) (bool, string) {
	return (userWeight & targetWeight) == targetWeight
}

特点:位计算高效,实现简单
缺陷:权限可读性不高,对复杂权限支持困难

权限复杂且动态添加

针对模块化的权限设置角色表,用户表与角色表做对应形成用户组。
角色表可以使用json格式存储每个角色对应功能的权限

type User struct {
	Id        uint   `gorm:"column:id" form:"id" json:"id" comment:"自增id" sql:"int(11),PRI"`
	Uid       string `gorm:"column:uid" form:"uid" json:"uid" comment:"内部id" sql:"varchar(40)"`
	Account   string `gorm:"column:account;unique_index:set_account" form:"account" json:"account" comment:"账号" sql:"varchar(255),UNI"`
	Password  string `gorm:"column:password" form:"password" json:"password" comment:"密码" sql:"varchar(255)"`
	Secretkey string `gorm:"column:secretkey" form:"secretkey" json:"-" comment:"找回密码用的秘钥" sql:"varchar(255)"`
	IsSuper   string `gorm:"column:is_super" form:"is_super" json:"is_super" comment:"是否是超级用户" sql:"varchar(1)"`
	NickName  string `gorm:"column:nick_name" form:"nick_name" json:"nick_name" comment:"昵称" sql:"varchar(255)"`
	Role      uint    `gorm:"column:role" form:"role" json:"role" comment:"角色id" sql:"int(11)"`
}
type Role struct {
	Id          uint               `gorm:"column:id" form:"id" json:"id" comment:"自增id" sql:"int(11),PRI"`
	Name        string             `gorm:"column:name" form:"name" json:"name" comment:"角色名" sql:"varchar(255)"`
	Description string             `gorm:"column:description" form:"description" json:"description" comment:"描述" sql:"varchar(255)"`
	Ext         string             `gorm:"column:ext" form:"ext" json:"-" comment:"保留字段" sql:"varchar(255)"`
	Permission  *types.StringArray `gorm:"type:json;column:permission" form:"permission" json:"permission" comment:"权限"`
}

type StringArray []string
func (data *StringArray) Scan(val interface{}) (err error) {
	if val == nil {
		return nil
	}
	if payload, ok := val.([]byte); ok {
		var value []string
		err = json.Unmarshal(payload, &value)
		if err == nil {
			*data = value
		}
	}
	return
}
func (data *StringArray) Value() (driver.Value, error) {
	if data == nil {
		return nil, nil
	}
	return json.Marshal([]string(*data))
}
func (data *StringArray) Get() []string {
	if data == nil {
		return nil
	}
	return []string(*data)
}

User.Role对应Role.Id
Role.Permission用字符串数组存储权限
权限定义为"接口的请求方法_接口"如:“get_/api/v1/user”
通过中间件进行权限检查

var apiInterfaceAuthCheckMiddleware = apiInterfaceAuthCheck()

func apiInterfaceAuthCheck() gin.HandlerFunc {
	return func(c *gin.Context) {
		user, ok := c.MustGet(gin.AuthUserKey).(*models.User)
		if !ok || user.Uid == "" {
			jsonError(c, "Need Administrator Account")
			return
		}
		method := c.Request.Method
		url := c.Request.URL.Path
		if !user.IsSuperAccount() {
			permissionFunc := strings.ToLower(fmt.Sprintf("%s_%s", method, url))
			haveAuth := models.CheckRolePermission(uint(user.Role), permissionFunc)
			if !haveAuth {
				jsonError(c, "Permission deny")
				return
			}
		}
		c.Next()
	}
}
//model.go
func CheckRolePermission(roleId uint, permissionFunc string)bool{
	if roleId == 0 {
		return false
	}
	mRole := Role{Id: roleId}
	role, err := mRole.One()
	if err != nil {
		return false
	}
	for _,permission := range *role.Permission{
		if strings.HasPrefix(permissionFunc,permission){
			return true
		}
	}
	return false
}

特点:灵活,对复杂权限可以动态添加,可读性高
缺陷:实现复杂,性能损失高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值