咱們來回顧一下上次分享的 GO中 gjson
庫的應用和分享,它主要是提供了一種很是快速且簡單的方式從json
文檔中獲取相應值mysql
json
與 gjson
分別表明什麼gjson
的簡單使用gjson
校驗,獲取值gjson
的 json 行
gjson
的鍵路徑匹配規則gjson
的修飾符和自定義修飾符要是對 gjson
還有點興趣的話,能夠查看文章 GO中gjson的應用和分享git
今天我們來分享一下 GO裏面的權限管理,Casbin
github
通常指根據系統設置的安全規則或者安全策略 算法
用戶能夠訪問並且只能訪問本身被受權的資源,很少很多剛恰好sql
權限管理幾乎出如今任何系統裏面數據庫
咱們可能會把 用戶身份認證
、 密碼加密
、 系統管理
與權限管理弄混淆,那麼他們具體的側重點是什麼呢?json
不屬於權限管理範疇segmentfault
用戶身份認證指的是經過某種憑證來證實本身的身份,例如帳號密碼,指紋,人臉識別等等後端
是系統中的一個模塊,該模塊通常還含有權限管理子模塊 , 該模塊至關於給權限管理模塊提供了一些數據api
也是不屬於權限管理範疇 , 他只是用戶身份認證領域的一個部分
是 GO 項目的功能強大且高效的開源訪問控制庫,casbin
支持經常使用的多種訪問控制模型,例如:
RBAC
ABAC
ACL
使用casbin
來作權限管理有一個比較好的地方是,casbin
是支持多種語言的,就像protobuf同樣也是支持多種語言
{subject, object, action}
,咱們也能夠自定義,同時他支持容許受權和拒絕受權
RBAC
中的角色層次結構 中,他能夠管理角色用戶映射和角色角色映射如root
或administrator
例如 hello/world
,就能夠將其映射到 hello*模式
Casbin
的基本模型在 Casbin
庫中,他是基於PERM
元模型將訪問控制模型抽象爲CONF文件,有以下4個部分
一塊兒來了解一個最簡單的模型,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, xiaomt, data1, read p, xiaomt, data2, write
main.go
文件寫gin
對應的接口以及 casbin
的使用rbac_models.conf
RBAC CONF文件
我們寫一個路由,裏面添加一個攔截器,再寫一個接口/api/v1/hello
,使用GET方法驗證效果
package main import ( "fmt" "log" "github.com/casbin/casbin" xd "github.com/casbin/xorm-adapter" "github.com/gin-gonic/gin" _ "github.com/go-sql-driver/mysql" ) // myAuth 攔截器 func myAuth(e *casbin.Enforcer) gin.HandlerFunc { return func(c *gin.Context) { obj := c.Request.URL.RequestURI() // 獲取方法 act := c.Request.Method sub := "root" // 判斷策略是否已經存在了 if ok := e.Enforce(sub, obj, act); ok { log.Println("Check successfully") c.Next() } else { log.Println("sorry , Check failed") c.Abort() } } } func main() { // 使用本身定義rbac_db // 最後的一個參數我們寫true ,不然默認爲false,使用缺省的數據庫名casbin,不存在則建立 a := xd.NewAdapter("mysql", "root:123456@tcp(127.0.0.1:3306)/mycasbin?charset=utf8", true) e := casbin.NewEnforcer("./rbac_models.conf", a) //從DB中 load 策略 e.LoadPolicy() //new 一個路由 r := gin.New() r.POST("/api/v1/add", func(c *gin.Context) { log.Println("add a policy") if ok := e.AddPolicy("root", "/api/v1/hello", "GET"); !ok { log.Println("The strategy already exists") } else { log.Println("add successfully ...") } }) //使用自定義攔截器中間件,每個接口的訪問,都會經過這個攔截器 r.Use(myAuth(e)) //建立請求 r.GET("/api/v1/hello", func(c *gin.Context) { fmt.Println("hello wolrd") }) // 監聽 127。0.0.1:8888 r.Run(":8888") }
對於上述 xd.NewAdapter
讀取數據的操做,我們能夠看看具體實現
具體源碼在 "github.com/casbin/xorm-adapter"
中的 adapter.go
// NewAdapter is the constructor for Adapter. // dbSpecified is an optional bool parameter. The default value is false. // It's up to whether you have specified an existing DB in dataSourceName. // If dbSpecified == true, you need to make sure the DB in dataSourceName exists. // If dbSpecified == false, the adapter will automatically create a DB named "casbin". func NewAdapter(driverName string, dataSourceName string, dbSpecified ...bool) *Adapter { a := &Adapter{} a.driverName = driverName a.dataSourceName = dataSourceName if len(dbSpecified) == 0 { a.dbSpecified = false } else if len(dbSpecified) == 1 { a.dbSpecified = dbSpecified[0] } else { panic(errors.New("invalid parameter: dbSpecified")) } // Open the DB, create it if not existed. a.open() // Call the destructor when the object is released. runtime.SetFinalizer(a, finalizer) return a }
再來看看casbin.NewEnforcer
源碼文件在 "github.com/casbin/casbin"
中 enforcer.go
NewEnforcer
經過文件或 DB 建立一個 enforcer
, 以下是官方的案例寫法,注意以下案例
// e := casbin.NewEnforcer("path/to/basic_model.conf", "path/to/basic_policy.csv") // MySQL DB: // a := mysqladapter.NewDBAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/") // e := casbin.NewEnforcer("path/to/basic_model.conf", a)
func NewEnforcer(params ...interface{}) *Enforcer { e := &Enforcer{} parsedParamLen := 0 // 判斷參數個數 if len(params) >= 1 { enableLog, ok := params[len(params)-1].(bool) if ok { e.EnableLog(enableLog) parsedParamLen++ } } // 省略 部分代碼 return e }
上述代碼,你們感興趣的話,能夠將代碼貼到本身的環境中
使用相似postman
工具來訪問接口,查看效果哦,須要配置好mysql
數據庫
對於上述的 gin
和攔截器
若感興趣的話, 能夠查看文章
朋友們,你的支持和鼓勵,是我堅持分享,提升質量的動力
好了,本次就到這裏,下一次 工做中後端是如何將API提供出去的?swaggo很不錯
技術是開放的,咱們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。
我是小魔童哪吒,歡迎點贊關注收藏,下次見~