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

本文涉及的产品
云原生网关 MSE Higress,422元/月
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
MSE Nacos/ZooKeeper 企业版试用,1600元额度,限量50份
简介: 管理后台有超管权限,超管拥有所有权限;普通管理员可以设置角色,角色单选;角色可以赋予多个权限,权限多选;这样我们就实现了对普通管理员的角色和权限的灵活管理

需求整理

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


文档说明

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


数据库表结构设计


管理员表


微信图片_20221111175906.jpg


权限表


微信图片_20221111175913.jpg


角色表


微信图片_20221111175917.jpg


角色表permission字段示意


微信图片_20221111175922.jpg


代码部分


路由文件


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": "更新成功"
}



公众号:程序员升级打怪之旅

微信号:wangzhongyang1993

相关文章
|
2月前
|
消息中间件 缓存 NoSQL
Redis各类数据结构详细介绍及其在Go语言Gin框架下实践应用
这只是利用Go语言和Gin框架与Redis交互最基础部分展示;根据具体业务需求可能需要更复杂查询、事务处理或订阅发布功能实现更多高级特性应用场景。
275 86
|
1月前
|
JSON 中间件 Java
【GoGin】(3)Gin的数据渲染和中间件的使用:数据渲染、返回JSON、浅.JSON()源码、中间件、Next()方法
我们在正常注册中间件时,会打断原有的运行流程,但是你可以在中间件函数内部添加Next()方法,这样可以让原有的运行流程继续执行,当原有的运行流程结束后再回来执行中间件内部的内容。​ c.Writer.WriteHeaderNow()还会写入文本流中。可以看到使用next后,正常执行流程中并没有获得到中间件设置的值。接口还提供了一个可以修改ContentType的方法。判断了传入的状态码是否符合正确的状态码,并返回。在内部封装时,只是标注了不同的render类型。再看一下其他返回的类型;
158 3
|
4月前
|
人工智能 负载均衡 监控
使用 Go 和 Gin 实现高可用负载均衡代理服务器
本文基于Go语言和Gin框架,实现了一个企业级负载均衡代理服务器,支持动态路由、健康检查、会话保持等功能。具备高可用性与高性能,单节点支持100k+ QPS,延迟达亚毫秒级,并提供完整的压力测试方案与优化建议。
157 7
|
5月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
5月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:使用 Gin 快速构建 Web 服务
Gin 是一个高效、轻量级的 Go 语言 Web 框架,支持中间件机制,非常适合开发 RESTful API。本文从安装到进阶技巧全面解析 Gin 的使用:快速入门示例(Hello Gin)、定义 RESTful 用户服务(增删改查接口实现),以及推荐实践如参数校验、中间件和路由分组等。通过对比标准库 `net/http`,Gin 提供更简洁灵活的开发体验。此外,还推荐了 GORM、Viper、Zap 等配合使用的工具库,助力高效开发。
|
缓存 前端开发 中间件
[go 面试] 前端请求到后端API的中间件流程解析
[go 面试] 前端请求到后端API的中间件流程解析
|
XML 监控 中间件
中间件消息发布者角色定位
【6月更文挑战第11天】
144 5
|
Go 数据安全/隐私保护
go 基于gin编写encode、decode、base64加密接口
go 基于gin编写encode、decode、base64加密接口
219 2
|
11月前
|
消息中间件 缓存 监控
go高并发之路——消息中间件kafka
本文介绍了高并发业务中的流量高峰应对措施,重点讲解了Kafka消息中间件的使用,包括常用的Go语言库sarama及其版本问题,以及Kafka的版本选择建议。文中还详细解释了Kafka生产者的四种分区策略:轮询、随机、按Key和指定分区,并提供了相应的代码示例。
321 1
go高并发之路——消息中间件kafka
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
1302 1