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

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
性能测试 PTS,5000VUM额度
简介: 管理后台有超管权限,超管拥有所有权限;普通管理员可以设置角色,角色单选;角色可以赋予多个权限,权限多选;这样我们就实现了对普通管理员的角色和权限的灵活管理

需求整理

  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

相关文章
|
6月前
|
中间件 Go 数据库
Go开发者必读:Gin框架的实战技巧与最佳实践
在当今快速发展的互联网时代,Web开发的需求日益增长。Go语言以其简洁、高效、并发性强的特点,成为了开发者们的首选。而在Go语言的众多Web框架中,Gin无疑是其中的佼佼者。本文将深入探讨Gin框架的特性、优势以及如何利用Gin构建高性能的Web应用。
|
6月前
|
中间件
gin中间件(Use)不能写在响应函数之后的原因——源码分析
gin中间件(Use)不能写在响应函数之后的原因——源码分析
103 0
|
3月前
|
缓存 前端开发 中间件
[go 面试] 前端请求到后端API的中间件流程解析
[go 面试] 前端请求到后端API的中间件流程解析
|
5月前
|
XML 监控 中间件
中间件消息发布者角色定位
【6月更文挑战第11天】
44 5
|
5月前
|
Go 数据安全/隐私保护
go 基于gin编写encode、decode、base64加密接口
go 基于gin编写encode、decode、base64加密接口
38 2
|
23天前
|
SQL 中间件 关系型数据库
那些年,我们在Go中间件上踩过的坑
作者总结了过去在Go中间件上踩过的坑,这些坑也促进了阿里内部Go中间件的完善,希望大家学习本文后,不犯同样的错误。
|
2月前
|
JSON Go API
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
|
2月前
|
消息中间件 NoSQL Go
PHP转Go系列 | ThinkPHP与Gin框架之Redis延时消息队列技术实践
【9月更文挑战第7天】在从 PHP 的 ThinkPHP 框架迁移到 Go 的 Gin 框架时,涉及 Redis 延时消息队列的技术实践主要包括:理解延时消息队列概念,其能在特定时间处理消息,适用于定时任务等场景;在 ThinkPHP 中使用 Redis 实现延时队列;在 Gin 中结合 Go 的 Redis 客户端库实现类似功能;Go 具有更高性能和简洁性,适合处理大量消息。迁移过程中需考虑业务需求及系统稳定性。
|
3月前
|
监控 中间件 Go
Go 中间件的优雅实现:处理请求的艺术
Go 中间件的优雅实现:处理请求的艺术
|
4月前
|
JSON 中间件 Go
Go语言Web框架Gin介绍
【7月更文挑战第19天】Gin是一个功能强大、高性能且易于使用的Go语言Web框架。它提供了路由、中间件、参数绑定等丰富的功能,帮助开发者快速构建高质量的Web应用。通过本文的介绍,你应该对Gin框架有了初步的了解,并能够使用它来开发简单的Web服务。随着你对Gin的深入学习和实践,你将能够利用它构建更复杂、更强大的Web应用。