iris集成Casbin-RBAC权限控制

2021-02-14  本文已影响0人  我爱张智容

casbin手册请看官网:
https://github.com/casbin/casbin
https://casbin.org/docs/zh-CN/overview

我的关键部分代码如下 :
main.go

package main

import (
    "github.com/kataras/iris/v12"
    "test/app/db"
    "test/config"
    "test/routes"
)

func main() {
    config.InitConfig()
    db.InitDB()
    db.InitCache()
    app := iris.Default()
    app.Logger().SetLevel("debug")
    routes.InitRoute(app)
    app.Listen(":8080")
}

route.go

package routes

import (
    "github.com/kataras/iris/v12"
    "test/app/api"
    "test/app/middlewares"
)

func InitRoute(app *iris.Application) {
    app.Get("/", api.Index.Index)

    //api部分 ApiAuth是自定义胡token验证, 后面才是包装的权限验证 
    middlewares.InitCasbin()
    apiGroup := app.Party("/api/v1", middlewares.ApiAuth, middlewares.Casbin.ServeHTTP)
    {
        apiGroup.Get("/user/login", api.User.Login)
    }

}

casbin_rbac.go

package middlewares

import (
    "github.com/casbin/casbin/v2"
    "github.com/casbin/casbin/v2/model"
    "github.com/kataras/golog"
    "github.com/kataras/iris/v12"
    "net/http"
    "test/app/db"
)

// 这个写法是把casbin包装了一下,
// 对外只暴露一个 Casbin ,调用就是 middleware.Casbin.XXX 
var Casbin *casbinAdapter

func InitCasbin() {
    Casbin = newCasbinAdapter()
}

type casbinAdapter struct {
    *casbin.Enforcer
}

func newCasbinAdapter() *casbinAdapter {
    m, err := model.NewModelFromString(`
[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) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
`)
    if err != nil {
        golog.Fatalf("casbin model config error : %s", err)
    }

    casbin, err2 := casbin.NewEnforcer(m, db.DB)
    if err2 != nil {
        golog.Fatalf("casbin init error : %s", err2)
    }
    return &casbinAdapter{Enforcer: casbin}
}

// 判断token
func (c *casbinAdapter) ServeHTTP(ctx iris.Context) {

    // TODO:TOKEN从header获取
    //value := ctx.Values().Get("jwt").(*jwt.Token)
    //token := dao.OauthToken{}
    //token.GetOauthTokenByToken(value.Raw) //获取 access_token 信息

    //测试代码start
    type reqMap struct {
        Uid string
    }
    token := reqMap{
        Uid: "10086",
    }
    //测试代码end

    if !c.Check(ctx.Request(), token.Uid) {
        ctx.StatusCode(http.StatusForbidden) // Status Forbidden
        ctx.StopExecution()
        return
    } else {
        ctx.Values().Set("uid", token.Uid)
    }

    ctx.Next()
}

// Check checks the username, request's method and path and
// returns true if permission grandted otherwise false.
func (c *casbinAdapter) Check(r *http.Request, uid string) bool {
    method := r.Method
    path := r.URL.Path
    ok, _ := c.Enforce(uid, path, method)
    return ok
}

最终还是要根据自身项目的实际情况去考虑如何集成。
本人实际的项目是RBAC权限验证,存储规则在xorm-mysql中。
以上仅作参考。

参考1:
https://blog.csdn.net/xyjworkgame/article/details/106449490
https://github.com/xyjworkgame/RBAC_GO

参考2 :
https://github.com/kataras/iris/tree/master/middleware
https://github.com/iris-contrib/middleware/tree/master/casbin

参考3:
https://www.dazhuanlan.com/2019/11/28/5ddf96c245be7/

参考4:
https://www.bilibili.com/video/BV1qz4y167XP
https://gitee.com/yhm_my/go-iris

完毕

上一篇下一篇

猜你喜欢

热点阅读