• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Go编写中间件, 用Gin实现【用户角色权限管理中间件】

武飞扬头像
juejin
帮助110

需求整理

  1. 管理后台有超管权限,超管拥有所有权限
  2. 普通管理员可以设置角色,角色单选
  3. 角色可以赋予多个权限,权限多选
  4. 这样我们就实现了对普通管理员的角色和权限的灵活管理

文档说明

  1. 基于golang语言开发
  2. 基于gin网络框架开发
  3. 基于MySQL5.8开发
  4. 把权限管理部分封装成中间件,在rourter文件中引用
  5. 非核心代码已省略,用3个竖着排列的点号.表示

数据库表结构设计

管理员表

管理员表

权限表

权限表

角色表

角色表

角色表permission字段示意

角色表permission字段示意

代码部分

路由文件

package server

import (
	.
	.
	.
	"os"
	"github.com/gin-gonic/gin"
)

// NewRouter 路由配置
func NewRouter() *gin.Engine {
	r := gin.Default()

	// 其他中间件
	.
	.
	.
	// 路由
	v1 := r.Group("/api/v1")
	{
		v1.POST("login", api.Login)
		auth := v1.Group("")
		//登录校验中间件
		auth.Use(middleware.AuthRequired())
		//关键代码:权限角色校验
		auth.Use(middleware.AuthCheckMiddleware)
		{
            .
            .
            .
			// 获取所有学校
			{
				auth.GET("/school/", api.GetSchoolInfo)
			}
			.
			.
			.
		}

	}
	return r
}

权限校验中间件代码

package middleware

import (
	.
	.
	.
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"strings"
)

var AuthCheckMiddleware = authCheck()
func authCheck() gin.HandlerFunc {
	return func(c *gin.Context) {
		if admin, _ := c.Get("admin"); admin != nil {
			method := c.Request.Method
			url := c.Request.URL.Path
			adminInfo := admin.(**service.RunningClaims)
			isSuper := (*adminInfo).IsSuper //是否是超管
			roleId := (*adminInfo).RoleId

			if isSuper != 1 {
				fmt.Println("method:", method)
				fmt.Println("url:", url)
				permissionFunc := strings.ToLower(fmt.Sprintf("%s_%s", method, url))
				haveAuth := model.CheckRolePermission(uint(roleId), permissionFunc)
				fmt.Println("haveAuth  ", haveAuth)
				if !haveAuth {
					c.JSON(http.StatusOK, api.ReturnJson{http.StatusForbidden, "", "无权访问"})
					c.Abort()
				}
			}
			c.Next()
		}
	}
}

角色model层代码

  1. CheckRolePermission是关键代码
//角色部分
type StringArray []string

//角色
type Role struct {
	Id          int          `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)"`
	Permission  *StringArray `gorm:"type:json;column:permission" form:"permission" json:"permission" comment:"权限"`
}

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 CheckRolePermission(roleId uint, permissionFunc string) bool {
	if roleId == 0 {
		return false
	}

	var myRole Role
	err := DB.Where("id = ?", roleId).First(&myRole).Error
	if err != gorm.ErrRecordNotFound {
		fmt.Printf("%v", myRole)
		permissions := myRole.Permission
		permissions.Scan(permissions)
		for _, permission := range *permissions {
			fmt.Println("permissionFunc:", permissionFunc)
			fmt.Println("permission:", permission)
			if strings.HasPrefix(permissionFunc, permission) {
				return true
			}
		}
	}
	return false
}

运行效果

有权限

{
    "code": 403,
    "data": "",
    "message": "无权访问"
}

无权限

{
    "code": 200,
    "data": true,
    "message": "更新成功"
}

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanfbage
系列文章
更多 icon
同类精品
更多 icon
继续加载