Go编写中间件, 用Gin实现【用户角色权限管理中间件】
需求整理
- 管理后台有超管权限,超管拥有所有权限
- 普通管理员可以设置角色,角色单选
- 角色可以赋予多个权限,权限多选
- 这样我们就实现了对普通管理员的角色和权限的灵活管理
文档说明
- 基于golang语言开发
- 基于gin网络框架开发
- 基于MySQL5.8开发
- 把权限管理部分封装成中间件,在rourter文件中引用
- 非核心代码已省略,用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层代码
- 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
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01