写点什么

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

作者:王中阳Go
  • 2022-10-17
    北京
  • 本文字数:1745 字

    阅读完需:约 1 分钟

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

需求整理

  1. 管理后台有超管权限,超管拥有所有权限

  2. 普通管理员可以设置角色,角色单选

  3. 角色可以赋予多个权限,权限多选

  4. 这样我们就实现了对普通管理员的角色和权限的灵活管理

文档说明

  1. 基于 golang 语言开发

  2. 基于 gin 网络框架开发

  3. 基于 MySQL5.8 开发

  4. 把权限管理部分封装成中间件,在 rourter 文件中引用

  5. 非核心代码已省略,用 3 个竖着排列的点号.表示

数据库表结构设计

管理员表



权限表



角色表



角色表 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": "更新成功"}
复制代码

后续

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

一起学习,升级打怪

我们搞了一个对学 Go 真正有帮助的群,欢迎加入:

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

微信号:wangzhongyang1993

发布于: 刚刚阅读数: 3
用户头像

王中阳Go

关注

公众号:程序员升级打怪之旅 2022-10-09 加入

微信:wangzhongyang1993

评论 (1 条评论)

发布
用户头像
这篇文章将带你结合商业项目需求,手撸一个Go语言Gin框架的中间件。解决用户角色权限管理的问题,中间件+goroutine又会摩擦出什么火花呢?
刚刚 · 北京
回复
没有更多了
你用Go写过中间件吗?带你用Gin实现【用户角色权限管理中间件】_golang_王中阳Go_InfoQ写作社区