前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你用Go写过中间件吗?带你用Gin实现【用户角色权限管理中间件】

你用Go写过中间件吗?带你用Gin实现【用户角色权限管理中间件】

作者头像
王中阳Go
发布2022-10-26 14:39:07
1.1K0
发布2022-10-26 14:39:07
举报
文章被收录于专栏:Go语言学习专栏

需求整理

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

文档说明

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

数据库表结构设计

管理员表

权限表

角色表

角色表permission字段示意

代码部分

路由文件

代码语言:javascript
复制
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
}

权限校验中间件代码

代码语言:javascript
复制
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是关键代码
代码语言:javascript
复制
//角色部分
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
}

运行效果

有权限

代码语言:javascript
复制
{
    "code": 403,
    "data": "",
    "message": "无权访问"
}

无权限

代码语言:javascript
复制
{
    "code": 200,
    "data": true,
    "message": "更新成功"
}

后续

下一章封装管理后台的操作日志管理:以中间件+goroutine的方式保存管理员的操作日志

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-09-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员升级打怪之旅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求整理
  • 文档说明
  • 数据库表结构设计
    • 管理员表
      • 权限表
        • 角色表
          • 角色表permission字段示意
          • 代码部分
            • 路由文件
              • 权限校验中间件代码
                • 角色model层代码
                • 运行效果
                  • 有权限
                    • 无权限
                    • 后续
                    相关产品与服务
                    消息队列 TDMQ
                    消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档