您好,登錄后才能下訂單哦!
詳情 可以查看 我寫的這個項目 https://github.com/hequan2017/go-admin
利用的庫:
github.com/casbin/casbin
github.com/gin-gonic/gin
github.com/facebookgo/inject
casbin文檔: https://casbin.org/zh-CN/
下面例子 未利用 casbin 的 adapter, 而是啟動的時候 先初始化,
然后通過數(shù)據(jù)庫里面的 對應關系 ,動態(tài)加載所有的 權限條目
然后通過中間件去判斷,如果有更新,可以動態(tài)修改更新 權限條目.
rbac_model.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) == true \
&& keyMatch3(r.obj, p.obj) == true \
&& regexMatch(r.act, p.act) == true
b_auth.go
package bll
//gin-allin/models 為自己的項目 請忽略
import (
"gin-allin/models"
"github.com/casbin/casbin"
)
//models.Auth 為 User表 實際可以寫成自己的USER 表
type Role struct {
Role *models.Auth `inject:""`
Enforcer *casbin.Enforcer `inject:""`
}
// LoadPolicy 加載角色權限策略,
func (a *Role) LoadPolicy(roleID string) error {
a.Enforcer.AddPolicy(roleID, "/api/v1/auth_info","GET")
return nil
}
b_common.go
package bll
//把 權限表 注入到 Common
type Common struct {
Role *Role `inject:""`
}
inject.go
package inject
import (
"gin-allin/bll"
"github.com/casbin/casbin"
"github.com/facebookgo/inject"
"os"
)
// Object 注入對象
type Object struct {
Common *bll.Common
Enforcer *casbin.Enforcer
}
// Init 初始化依賴注入
func Init() *Object {
g := new(inject.Graph)
// 注入casbin
dir, _ := os.Getwd()
path := dir + "\\src\\gin-allin\\conf\\rbac_model.conf"
enforcer := casbin.NewEnforcer(path, false)
_ = g.Provide(&inject.Object{Value: enforcer})
// 注入Common 也就是 Role
Common := new(bll.Common)
_ = g.Provide(&inject.Object{Value: Common})
if err := g.Populate(); err != nil {
panic("初始化依賴注入發(fā)生錯誤:" + err.Error())
}
// 返回 注入完的對象
return &Object{
Enforcer: enforcer,
Common :Common,
}
}
casb.go
package casb
import (
"gin-allin/inject"
"github.com/gin-gonic/gin"
"net/http"
)
// 權限判斷
func CasbinMiddleware(obj *inject.Object) gin.HandlerFunc {
return func(c *gin.Context) {
// 判斷 權限 是否為 true
if b, err := obj.Enforcer.EnforceSafe("hequan", c.Request.URL.Path, c.Request.Method); err != nil {
c.JSON(http.StatusUnauthorized, gin.H{
"code": "權限 判斷錯誤",
"msg": "權限 判斷錯誤",
"data": "權限 判斷錯誤",
})
c.Abort()
return
} else if !b {
c.JSON(http.StatusUnauthorized, gin.H{
"code": "沒有權限",
"msg": "沒有權限",
"data": "沒有權限",
})
c.Abort()
return
}
c.Next()
}
}
router.go
package routers
func InitRouter() *gin.Engine {
// 生成對象
obj := inject.Init()
err := loadCasbinPolicyData(obj)
if err != nil {
panic("加載casbin策略數(shù)據(jù)發(fā)生錯誤:" + err.Error())
}
apiv1.Use(casb.CasbinMiddleware(obj))
}
// 加載casbin策略數(shù)據(jù) 加載 hequan 的一個權限
func loadCasbinPolicyData(obj *inject.Object) error {
err := obj.Common.Role.LoadPolicy("hequan")
if err != nil {
fmt.Println(err)
return err
}
return nil
}
當 用戶 hequan 去 訪問 /api/v1/auth_info 時,會去判斷是否有GET 權限,有就通過,沒有就拒絕。
測試 可以把 用戶名 寫成其他的, 再重新啟動,此時,中間件判斷 不通過,就會返回 拒絕。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。