• go语言web开发系列之十一:gin框架通过casbin实现rbac权限设计(csv存储)


    一,安装casbin

    1,casbin项目代码的地址

    https://github.com/casbin/casbin

    2,为go安装casbin

    liuhongdi@ku:~$ go get -u github.com/casbin/casbin/v2

    说明:刘宏缔的go森林是一个专注golang的博客,
              地址:https://blog.csdn.net/weixin_43881017

    说明:作者:刘宏缔 邮箱: 371125307@qq.com

    二,演示项目的相关信息

    1,项目地址

    https://github.com/liuhongdi/digv11

    2,项目功能说明:

       /admin/* :只有role为 superAdmin时可访问

      /article/* : role为superAdmin/user时均可访问

      /home/*:   role为任何用户时均可访问

    3,项目结构:如图:

    三,配置文件说明:

    1,config/rbac_model.conf

    1.  
      # Request definition 自定义请求的格式
    2.  
      [request_definition]
    3.  
      r = sub, obj, act
    4.  
       
    5.  
      # Policy definition 策略定义
    6.  
      [policy_definition]
    7.  
      p = sub, obj, act
    8.  
       
    9.  
      # Policy effect
    10.  
      [policy_effect]
    11.  
      e = some(where (p.eft == allow))
    12.  
       
    13.  
      # Matchers
    14.  
      [matchers]
    15.  
      #m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
    16.  
      m = (r.sub == p.sub || p.sub == "*") && keyMatch(r.obj,p.obj) && (r.act == p.act || p.act == "*")

    2,rbac2.csv

    1.  
      p,superAdmin,/article/*,*
    2.  
      p,superAdmin,/admin/*,*
    3.  
      p,*,/home/*,*
    4.  
      p,user,/article/*,*

    说明:csv文件必须用相应的软件生成,如图:

    四,go代码说明

    1,homeController.go

    1.  
      package controller
    2.  
       
    3.  
      import (
    4.  
      "github.com/gin-gonic/gin"
    5.  
      "github.com/liuhongdi/digv11/pkg/result"
    6.  
      )
    7.  
       
    8.  
      type HomeController struct{}
    9.  
       
    10.  
      func NewHomeController() HomeController {
    11.  
      return HomeController{}
    12.  
      }
    13.  
      //首页,任何人可访问,不登录也可访问
    14.  
      func (a *HomeController) Home(c *gin.Context) {
    15.  
      resultRes := result.NewResult(c)
    16.  
      resultRes.Success("this is home page");
    17.  
      return
    18.  
      }

    2,adminController.go

    1.  
      package controller
    2.  
       
    3.  
      import (
    4.  
      "github.com/gin-gonic/gin"
    5.  
      "github.com/liuhongdi/digv11/pkg/result"
    6.  
      )
    7.  
       
    8.  
      type HomeController struct{}
    9.  
       
    10.  
      func NewHomeController() HomeController {
    11.  
      return HomeController{}
    12.  
      }
    13.  
      //首页,任何人可访问,不登录也可访问
    14.  
      func (a *HomeController) Home(c *gin.Context) {
    15.  
      resultRes := result.NewResult(c)
    16.  
      resultRes.Success("this is home page");
    17.  
      return
    18.  
      }

    3,ArticleController.go

    1.  
      package controller
    2.  
       
    3.  
      import (
    4.  
      "fmt"
    5.  
      "github.com/gin-gonic/gin"
    6.  
      "github.com/liuhongdi/digv11/pkg/page"
    7.  
      "github.com/liuhongdi/digv11/pkg/result"
    8.  
      "github.com/liuhongdi/digv11/pkg/validCheck"
    9.  
      "github.com/liuhongdi/digv11/request"
    10.  
      "github.com/liuhongdi/digv11/service"
    11.  
      )
    12.  
       
    13.  
      type ArticleController struct{}
    14.  
       
    15.  
      func NewArticleController() ArticleController {
    16.  
      return ArticleController{}
    17.  
      }
    18.  
      //得到一篇文章的详情
    19.  
      func (a *ArticleController) GetOne(c *gin.Context) {
    20.  
      result := result.NewResult(c)
    21.  
      param := request.ArticleRequest{ID: validCheck.StrTo(c.Param("id")).MustUInt64()}
    22.  
      valid, errs := validCheck.BindAndValid(c, &param)
    23.  
      if !valid {
    24.  
      result.Error(400,errs.Error())
    25.  
      return
    26.  
      }
    27.  
       
    28.  
      if (param.ID == 100) {
    29.  
      var z int = 0
    30.  
      var i int = 100 / z
    31.  
      fmt.Println("i:%i",i)
    32.  
      }
    33.  
       
    34.  
      articleOne,err := service.GetOneArticle(param.ID);
    35.  
      if err != nil {
    36.  
      result.Error(404,"数据查询错误")
    37.  
      } else {
    38.  
      result.Success(&articleOne);
    39.  
      }
    40.  
      return
    41.  
      }
    42.  
       

    4,global/casbin.go

    1.  
      package global
    2.  
       
    3.  
      import (
    4.  
      "fmt"
    5.  
      "github.com/casbin/casbin/v2"
    6.  
      "log"
    7.  
      "os"
    8.  
      )
    9.  
       
    10.  
      var (
    11.  
      Enforcer *casbin.Enforcer
    12.  
      )
    13.  
       
    14.  
      //创建casbin的enforcer
    15.  
      func SetupCasbinEnforcer() (error) {
    16.  
      dir, _ := os.Getwd()
    17.  
      modelPath := dir + "/config/rbac_model.conf"
    18.  
      csvPath := dir + "/config/rbac2.csv"
    19.  
      fmt.Println("modelPath:"+modelPath);
    20.  
      fmt.Println("csvPath:"+csvPath);
    21.  
      var errC error
    22.  
      Enforcer, errC = casbin.NewEnforcer(modelPath, csvPath)
    23.  
      //fmt.Printf("RBAC test start ") // output for debug
    24.  
      if (errC != nil) {
    25.  
      //fmt.Println(errC)
    26.  
      log.Fatalf("SetupCasbinEnforcer err: %v", errC)
    27.  
      return errC
    28.  
      } else {
    29.  
      Enforcer.EnableLog(true)
    30.  
      return nil
    31.  
      }
    32.  
      }

    5,main.go

    1.  
      package main
    2.  
       
    3.  
      import (
    4.  
      "github.com/gin-gonic/gin"
    5.  
      _ "github.com/jinzhu/gorm/dialects/mysql"
    6.  
      "github.com/liuhongdi/digv11/global"
    7.  
      "github.com/liuhongdi/digv11/router"
    8.  
      "log"
    9.  
      )
    10.  
       
    11.  
      //init
    12.  
      func init() {
    13.  
      //setting
    14.  
      err := global.SetupSetting()
    15.  
      if err != nil {
    16.  
      log.Fatalf("init.setupSetting err: %v", err)
    17.  
      }
    18.  
       
    19.  
      //logger
    20.  
      err = global.SetupLogger()
    21.  
      if err != nil {
    22.  
      log.Fatalf("init.SetupLogger err: %v", err)
    23.  
      }
    24.  
       
    25.  
      //access logger
    26.  
      err = global.SetupAccessLogger()
    27.  
      if err != nil {
    28.  
      log.Fatalf("init.SetupAccessLogger err: %v", err)
    29.  
      }
    30.  
       
    31.  
      //casbin
    32.  
      err = global.SetupCasbinEnforcer()
    33.  
      if err != nil {
    34.  
      log.Fatalf("init.SetupCasbinEnforcer err: %v", err)
    35.  
      global.Logger.Fatalf("init.SetupCasbinEnforcer err: %v", err)
    36.  
      }
    37.  
       
    38.  
      //db
    39.  
      err = global.SetupDBLink()
    40.  
      if err != nil {
    41.  
      log.Fatalf("init.SetupLogger err: %v", err)
    42.  
      global.Logger.Fatalf("init.setupDBEngine err: %v", err)
    43.  
      }
    44.  
       
    45.  
      global.Logger.Infof("------应用init结束")
    46.  
      //global.Logger.
    47.  
      }
    48.  
       
    49.  
      func main() {
    50.  
       
    51.  
       
    52.  
      global.Logger.Infof("------应用main函数开始")
    53.  
      //设置运行模式
    54.  
      gin.SetMode(global.ServerSetting.RunMode)
    55.  
      //引入路由
    56.  
      r := router.Router()
    57.  
      //run
    58.  
      r.Run(":"+global.ServerSetting.HttpPort)
    59.  
      }

    6,middleware/permission.go

    1.  
      package middleware
    2.  
       
    3.  
      import (
    4.  
      "fmt"
    5.  
      "github.com/gin-gonic/gin"
    6.  
      "github.com/liuhongdi/digv11/global"
    7.  
      "github.com/liuhongdi/digv11/pkg/result"
    8.  
      )
    9.  
       
    10.  
      func PermissionMiddleWare() gin.HandlerFunc {
    11.  
      return func(c *gin.Context) {
    12.  
       
    13.  
      // 请求的path
    14.  
      p := c.Request.URL.Path
    15.  
      // 请求的方法
    16.  
      m := c.Request.Method
    17.  
       
    18.  
      role:="superAdmin"
    19.  
      //role:="user"
    20.  
      //role:="guest"
    21.  
       
    22.  
      fmt.Println("role:"+role)
    23.  
      fmt.Println("path:"+p)
    24.  
      fmt.Println("method:"+m)
    25.  
       
    26.  
      // 检查用户权限
    27.  
      isPass, err := global.Enforcer.Enforce(role, p, m)
    28.  
      if err != nil {
    29.  
      resultRes := result.NewResult(c)
    30.  
      resultRes.Error(2005,err.Error())
    31.  
      return
    32.  
      }
    33.  
      if isPass {
    34.  
      c.Next()
    35.  
      } else {
    36.  
      resultRes := result.NewResult(c)
    37.  
      resultRes.Error(2006,"无访问权限")
    38.  
      return
    39.  
      }
    40.  
      }
    41.  
      }

    7,其他相关代码可访问github

    五,测试效果

    1,middleware/permission.go中,

      role:="guest"

    访问:

    http://127.0.0.1:8000/home/home

    返回:

    访问:

    http://127.0.0.1:8000/article/getone/2

    返回:

    访问:

    http://127.0.0.1:8000/admin/admin

    返回:

    2,middleware/permission.go中,

    role:="user"

    访问:

    http://127.0.0.1:8000/home/home

    返回:

    访问:

    http://127.0.0.1:8000/article/getone/2

    返回:

    访问:

    http://127.0.0.1:8000/admin/admin

    返回:

    3,middleware/permission.go中,

    role:="superAdmin"

    访问:

    http://127.0.0.1:8000/home/home

    返回:

    访问:

    http://127.0.0.1:8000/article/getone/2

    返回:

    访问:

    http://127.0.0.1:8000/admin/admin

    返回:

    六,查看库的版本:

    1.  
      module github.com/liuhongdi/digv11
    2.  
       
    3.  
      go 1.15
    4.  
       
    5.  
      require (
    6.  
      github.com/gin-gonic/gin v1.6.3
    7.  
      github.com/go-playground/universal-translator v0.17.0
    8.  
      github.com/go-playground/validator/v10 v10.2.0
    9.  
      github.com/jinzhu/gorm v1.9.16
    10.  
      github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f
    11.  
      github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
    12.  
      github.com/magiconair/properties v1.8.4 // indirect
    13.  
      github.com/mitchellh/mapstructure v1.3.3 // indirect
    14.  
      github.com/pelletier/go-toml v1.8.1 // indirect
    15.  
      github.com/pkg/errors v0.9.1 // indirect
    16.  
      github.com/spf13/afero v1.4.1 // indirect
    17.  
      github.com/spf13/cast v1.3.1 // indirect
    18.  
      github.com/spf13/jwalterweatherman v1.1.0 // indirect
    19.  
      github.com/spf13/pflag v1.0.5 // indirect
    20.  
      github.com/spf13/viper v1.7.1
    21.  
      github.com/casbin/casbin/v2 v2.17.0
    22.  
      go.uber.org/multierr v1.6.0 // indirect
    23.  
      go.uber.org/zap v1.16.0
    24.  
      golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
    25.  
      golang.org/x/text v0.3.4 // indirect
    26.  
      gopkg.in/ini.v1 v1.62.0 // indirect
    27.  
      gopkg.in/yaml.v2 v2.3.0 // indirect
    28.  
      )
  • 相关阅读:
    C++中左移<<的使用
    学会构造素数序列
    有关lower_bound()函数的使用
    Codeforces Round #166 (Div. 2)
    暴力swap导致TLE问题解决办法
    memset的正确使用
    Codeforces Round #297 (Div. 2)
    Codeforces Round #170 (Div. 2)B
    Codeforces Round #176 (Div. 2)
    C/C++ sort函数的用法
  • 原文地址:https://www.cnblogs.com/ExMan/p/14312240.html
Copyright © 2020-2023  润新知