一,安裝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
-
# Request definition 自定義請求的格式
-
[request_definition]
-
r = sub, obj, act
-
-
# Policy definition 策略定義
-
[policy_definition]
-
p = sub, obj, act
-
-
# Policy effect
-
[policy_effect]
-
e = some( where (p.eft == allow))
-
-
# Matchers
-
[matchers]
-
#m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
-
m = (r.sub == p.sub || p.sub == "*") && keyMatch(r.obj,p.obj) && (r.act == p.act || p.act == "*")
2,rbac2.csv
-
p,superAdmin,/article/*,*
-
p,superAdmin,/admin/*,*
-
p,*,/home/*,*
-
p,user,/article/*,*
說明:csv文件必須用相應的軟件生成,如圖:
四,go代碼說明
1,homeController.go
-
package controller
-
-
import (
-
"github.com/gin-gonic/gin"
-
"github.com/liuhongdi/digv11/pkg/result"
-
)
-
-
type HomeController struct{}
-
-
func NewHomeController() HomeController {
-
return HomeController{}
-
}
-
//首頁,任何人可訪問,不登錄也可訪問
-
func (a *HomeController) Home(c *gin.Context) {
-
resultRes := result.NewResult(c)
-
resultRes.Success( "this is home page");
-
return
-
}
2,adminController.go
-
package controller
-
-
import (
-
"github.com/gin-gonic/gin"
-
"github.com/liuhongdi/digv11/pkg/result"
-
)
-
-
type HomeController struct{}
-
-
func NewHomeController() HomeController {
-
return HomeController{}
-
}
-
//首頁,任何人可訪問,不登錄也可訪問
-
func (a *HomeController) Home(c *gin.Context) {
-
resultRes := result.NewResult(c)
-
resultRes.Success( "this is home page");
-
return
-
}
3,ArticleController.go
-
package controller
-
-
import (
-
"fmt"
-
"github.com/gin-gonic/gin"
-
"github.com/liuhongdi/digv11/pkg/page"
-
"github.com/liuhongdi/digv11/pkg/result"
-
"github.com/liuhongdi/digv11/pkg/validCheck"
-
"github.com/liuhongdi/digv11/request"
-
"github.com/liuhongdi/digv11/service"
-
)
-
-
type ArticleController struct{}
-
-
func NewArticleController() ArticleController {
-
return ArticleController{}
-
}
-
//得到一篇文章的詳情
-
func (a *ArticleController) GetOne(c *gin.Context) {
-
result := result.NewResult(c)
-
param := request.ArticleRequest{ID: validCheck.StrTo(c.Param( "id")).MustUInt64()}
-
valid, errs := validCheck.BindAndValid(c, ¶m)
-
if !valid {
-
result.Error( 400,errs.Error())
-
return
-
}
-
-
if (param.ID == 100) {
-
var z int = 0
-
var i int = 100 / z
-
fmt.Println( "i:%i",i)
-
}
-
-
articleOne,err := service.GetOneArticle(param.ID);
-
if err != nil {
-
result.Error( 404,"數據查詢錯誤")
-
} else {
-
result.Success(&articleOne);
-
}
-
return
-
}
-
4,global/casbin.go
-
package global
-
-
import (
-
"fmt"
-
"github.com/casbin/casbin/v2"
-
"log"
-
"os"
-
)
-
-
var (
-
Enforcer *casbin.Enforcer
-
)
-
-
//創建casbin的enforcer
-
func SetupCasbinEnforcer() (error) {
-
dir, _ := os.Getwd()
-
modelPath := dir + "/config/rbac_model.conf"
-
csvPath := dir + "/config/rbac2.csv"
-
fmt.Println( "modelPath:"+modelPath);
-
fmt.Println( "csvPath:"+csvPath);
-
var errC error
-
Enforcer, errC = casbin.NewEnforcer(modelPath, csvPath)
-
//fmt.Printf("RBAC test start\n") // output for debug
-
if (errC != nil) {
-
//fmt.Println(errC)
-
log.Fatalf( "SetupCasbinEnforcer err: %v", errC)
-
return errC
-
} else {
-
Enforcer.EnableLog( true)
-
return nil
-
}
-
}
5,main.go
-
package main
-
-
import (
-
"github.com/gin-gonic/gin"
-
_ "github.com/jinzhu/gorm/dialects/mysql"
-
"github.com/liuhongdi/digv11/global"
-
"github.com/liuhongdi/digv11/router"
-
"log"
-
)
-
-
//init
-
func init() {
-
//setting
-
err := global.SetupSetting()
-
if err != nil {
-
log.Fatalf( "init.setupSetting err: %v", err)
-
}
-
-
//logger
-
err = global.SetupLogger()
-
if err != nil {
-
log.Fatalf( "init.SetupLogger err: %v", err)
-
}
-
-
//access logger
-
err = global.SetupAccessLogger()
-
if err != nil {
-
log.Fatalf( "init.SetupAccessLogger err: %v", err)
-
}
-
-
//casbin
-
err = global.SetupCasbinEnforcer()
-
if err != nil {
-
log.Fatalf( "init.SetupCasbinEnforcer err: %v", err)
-
global.Logger.Fatalf( "init.SetupCasbinEnforcer err: %v", err)
-
}
-
-
//db
-
err = global.SetupDBLink()
-
if err != nil {
-
log.Fatalf( "init.SetupLogger err: %v", err)
-
global.Logger.Fatalf( "init.setupDBEngine err: %v", err)
-
}
-
-
global.Logger.Infof( "------應用init結束")
-
//global.Logger.
-
}
-
-
func main() {
-
-
-
global.Logger.Infof( "------應用main函數開始")
-
//設置運行模式
-
gin.SetMode(global.ServerSetting.RunMode)
-
//引入路由
-
r := router.Router()
-
//run
-
r.Run( ":"+global.ServerSetting.HttpPort)
-
}
6,middleware/permission.go
-
package middleware
-
-
import (
-
"fmt"
-
"github.com/gin-gonic/gin"
-
"github.com/liuhongdi/digv11/global"
-
"github.com/liuhongdi/digv11/pkg/result"
-
)
-
-
func PermissionMiddleWare() gin.HandlerFunc {
-
return func(c *gin.Context) {
-
-
// 請求的path
-
p := c.Request.URL.Path
-
// 請求的方法
-
m := c.Request.Method
-
-
role:= "superAdmin"
-
//role:="user"
-
//role:="guest"
-
-
fmt.Println( "role:"+role)
-
fmt.Println( "path:"+p)
-
fmt.Println( "method:"+m)
-
-
// 檢查用戶權限
-
isPass, err := global.Enforcer.Enforce(role, p, m)
-
if err != nil {
-
resultRes := result.NewResult(c)
-
resultRes.Error( 2005,err.Error())
-
return
-
}
-
if isPass {
-
c.Next()
-
} else {
-
resultRes := result.NewResult(c)
-
resultRes.Error( 2006,"無訪問權限")
-
return
-
}
-
}
-
}
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
返回:
六,查看庫的版本:
-
module github.com/liuhongdi/digv11
-
-
go 1.15
-
-
require (
-
github.com/gin-gonic/gin v1.6.3
-
github.com/go-playground/universal-translator v0.17.0
-
github.com/go-playground/validator/v10 v10.2.0
-
github.com/jinzhu/gorm v1.9.16
-
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f
-
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
-
github.com/magiconair/properties v1.8.4 // indirect
-
github.com/mitchellh/mapstructure v1.3.3 // indirect
-
github.com/pelletier/go-toml v1.8.1 // indirect
-
github.com/pkg/errors v0.9.1 // indirect
-
github.com/spf13/afero v1.4.1 // indirect
-
github.com/spf13/cast v1.3.1 // indirect
-
github.com/spf13/jwalterweatherman v1.1.0 // indirect
-
github.com/spf13/pflag v1.0.5 // indirect
-
github.com/spf13/viper v1.7.1
-
github.com/casbin/casbin/v2 v2.17.0
-
go.uber.org/multierr v1.6.0 // indirect
-
go.uber.org/zap v1.16.0
-
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
-
golang.org/x/text v0.3.4 // indirect
-
gopkg.in/ini.v1 v1.62.0 // indirect
-
gopkg.in/yaml.v2 v2.3.0 // indirect
-
)