Go gin权限验证实现过程详解

 更新时间:2023年01月08日 10:18:23   作者:夏沫的梦  
这篇文章主要为大家介绍了Go gin权限验证实现过程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

权限管理

Casbin是用于Golang项目的功能强大且高效的开源访问控制库。

1. 特征

Casbin的作用:

  • 以经典{subject, object, action}形式或您定义的自定义形式实施策略,同时支持允许和拒绝授权。
  • 处理访问控制模型及其策略的存储。
  • 管理角色用户映射和角色角色映射(RBAC中的角色层次结构)。
  • 支持内置的超级用户,例如root或administrator。超级用户可以在没有显式权限的情况下执行任何操作。
  • 多个内置运算符支持规则匹配。例如,keyMatch可以将资源键映射/foo/bar到模式/foo*。 Casbin不执行的操作:
  • 身份验证(又名验证username以及password用户登录时)
  • 管理用户或角色列表。我相信项目本身管理这些实体会更方便。用户通常具有其密码,而Casbin并非设计为密码- 容器。但是,Casbin存储RBAC方案的用户角色映射。

2. 怎么运行的

在Casbin中,基于PERM元模型(策略,效果,请求,匹配器)将访问控制模型抽象为CONF文件。因此,切换或升级项目的授权机制就像修改配置一样简单。您可以通过组合可用的模型来定制自己的访问控制模型。例如,您可以在一个模型中同时获得RBAC角色和ABAC属性,并共享一组策略规则。

Casbin中最基本,最简单的模型是ACL。ACL的CONF模型为:

#请求定义
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

ACL模型的示例策略如下:

p, alice, data1, read
p, bob, data2, write

3. 安装

go get github.com/casbin/casbin

4. 示例代码

package main
import (
    "fmt"
    "log"
    "github.com/casbin/casbin"
    xormadapter "github.com/casbin/xorm-adapter"
    "github.com/gin-gonic/gin"
    _ "github.com/go-sql-driver/mysql"
)
func main() {
    // 要使用自己定义的数据库rbac_db,最后的true很重要.默认为false,使用缺省的数据库名casbin,不存在则创建
    a, err := xormadapter.NewAdapter("mysql", "root:root@tcp(127.0.0.1:3306)/goblog?charset=utf8", true)
    if err != nil {
        log.Printf("连接数据库错误: %v", err)
        return
    }
    e, err := casbin.NewEnforcer("./rbac_models.conf", a)
    if err != nil {
        log.Printf("初始化casbin错误: %v", err)
        return
    }
    //从DB加载策略
    e.LoadPolicy()
    //获取router路由对象
    r := gin.New()
    r.POST("/api/v1/add", func(c *gin.Context) {
        fmt.Println("增加Policy")
        if ok, _ := e.AddPolicy("admin", "/api/v1/hello", "GET"); !ok {
            fmt.Println("Policy已经存在")
        } else {
            fmt.Println("增加成功")
        }
    })
    //删除policy
    r.DELETE("/api/v1/delete", func(c *gin.Context) {
        fmt.Println("删除Policy")
        if ok, _ := e.RemovePolicy("admin", "/api/v1/hello", "GET"); !ok {
            fmt.Println("Policy不存在")
        } else {
            fmt.Println("删除成功")
        }
    })
    //获取policy
    r.GET("/api/v1/get", func(c *gin.Context) {
        fmt.Println("查看policy")
        list := e.GetPolicy()
        for _, vlist := range list {
            for _, v := range vlist {
                fmt.Printf("value: %s, ", v)
            }
        }
    })
    //使用自定义拦截器中间件
    r.Use(Authorize(e))
    //创建请求
    r.GET("/api/v1/hello", func(c *gin.Context) {
        fmt.Println("Hello 接收到GET请求..")
    })
    r.Run(":9000") //参数为空 默认监听8080端口
}
//拦截器
func Authorize(e *casbin.Enforcer) gin.HandlerFunc {
    return func(c *gin.Context) {
        //获取请求的URI
        obj := c.Request.URL.RequestURI()
        //获取请求方法
        act := c.Request.Method
        //获取用户的角色
        sub := "admin"
        //判断策略中是否存在
        if ok, _ := e.Enforce(sub, obj, act); ok {
            fmt.Println("恭喜您,权限验证通过")
            c.Next()
        } else {
            fmt.Println("很遗憾,权限验证没有通过")
            c.Abort()
        }
    }
}

rbac_models.conf里面的内容如下:

[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

配置链接数据库不需要手动创建数据库,系统自动创建casbin_rule表

使用postman请求http://localhost:9000/api/v1/hello

运行解决结果显示为很遗憾,权限验证没有通过

下面我在数据表中添加数据在演示的时候可以直接手动按照图片的格式直接添加数据表,或者使用postman POST方式请求http://localhost:9000/api/v1/add

然后继续请求http://localhost:9000/api/v1/hello

以上就是Go gin权限验证实现过程详解的详细内容,更多关于Go gin权限验证的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言学习之条件语句使用详解

    Go语言学习之条件语句使用详解

    这篇文章主要介绍了Go语言中条件语句的使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • golang qq邮件发送验证码功能

    golang qq邮件发送验证码功能

    验证码在多个场景下发挥着重要作用,如注册/登录、短信接口保护、提交/投票、密码找回和支付验证等,以保障账号安全和防止恶意操作,此外,文章还介绍了使用golang通过qq邮件发送验证码的实现过程,包括获取授权码、下载依赖包和编写代码,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • 浅析Go语言中的map数据结构是如何实现的

    浅析Go语言中的map数据结构是如何实现的

    在 Go 中,map 是一种用于存储键值对的数据结构,它提供了一种快速查找和访问数据的方式,下面我们就来看看Go语言中是如何实现map数据结构的吧
    2024-03-03
  • Go语言实现JSON解析的方法详解

    Go语言实现JSON解析的方法详解

    在日常项目中,使用Json格式进行数据封装是比较常见的操作。本文将详细讲解如何利用Go语言实现JSON的解析,感兴趣的小伙伴可以学习一下
    2022-04-04
  • Go语言实现Fibonacci数列的方法

    Go语言实现Fibonacci数列的方法

    这篇文章主要介绍了Go语言实现Fibonacci数列的方法,实例分析了使用递归和不使用递归两种技巧,并对算法的效率进行了对比,需要的朋友可以参考下
    2015-02-02
  • Go调度器学习之系统调用详解

    Go调度器学习之系统调用详解

    这篇文章肿,将以一个简单的文件打开的系统调用,来分析一下Go调度器在系统调用时做了什么。文中的示例代码讲解详细,需要的可以参考一下
    2023-04-04
  • Golang定时器Timer与Ticker的使用详解

    Golang定时器Timer与Ticker的使用详解

    在 Go 里有很多种定时器的使用方法,像常规的 Timer、Ticker 对象,本文主要为大家介绍了Timer与Ticker的使用,感兴趣的小伙伴可以了解一下
    2023-05-05
  • Golang性能提升利器之SectionReader的用法详解

    Golang性能提升利器之SectionReader的用法详解

    本文将介绍 Go 语言中的 SectionReader,包括 SectionReader的基本使用方法、实现原理、使用注意事项,感兴趣的小伙伴可以了解一下
    2023-07-07
  • go swagger生成接口文档使用教程

    go swagger生成接口文档使用教程

    这篇文章主要为大家介绍了go swagger生成接口文档使用教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 一文理解Go 中的可寻址和不可寻址

    一文理解Go 中的可寻址和不可寻址

    如果字典的元素不存在,则返回零值,而零值是不可变对象,如果能寻址问题就大了。而如果字典的元素存在,考虑到 Go 中 map 实现中元素的地址是变化的,这意味着寻址的结果也是无意义的。下面我们就围绕这个话题写一篇文章吧,需要的朋友可以参考一下
    2021-10-10

最新评论