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\n") // 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.  
    )


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM