项目地址:
https://casbin.org/zh/docs/overview
示例代码:
基于文件:
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] # root 是超级用户 m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act || r.sub == "root"
policy.csv
:p, admin, /test, POST p, admin, /test, DELETE p, a, /test, PUT g, a, admin
main.go
:package main import ( "fmt" "github.com/casbin/casbin/v2" "github.com/gin-gonic/gin" "net/http" ) var ( e *casbin.Enforcer err error ) func init() { e, err = casbin.NewEnforcer("model.conf", "policy.csv") if err != nil { panic(err) } } func checkPermission(ctx *gin.Context) { sub := ctx.GetHeader("user") obj := ctx.Request.URL.Path act := ctx.Request.Method ok, err := e.Enforce(sub, obj, act) if err != nil { ctx.String(http.StatusInternalServerError, "内部服务器错误") ctx.Abort() } if !ok { ctx.String(http.StatusOK, "权限验证不通过") ctx.Abort() } fmt.Println("权限验证通过") ctx.Next() } func main() { r := gin.Default() r.Use(checkPermission) // 新增策略 r.PUT("/policy", func(ctx *gin.Context) { sub := ctx.Query("user") obj := ctx.Query("path") act := ctx.Query("method") role := ctx.Query("group") if ok, err := e.AddPolicy(sub, obj, act); !ok || err != nil { ctx.String(http.StatusOK, "新增策略失败") return } if role != "" { if ok, err := e.AddRoleForUser(sub, role); !ok || err != nil { ctx.String(http.StatusOK, "新增策略分组失败") return } } // 写入策略(保存到文件/数据库) e.SavePolicy() ctx.String(http.StatusOK, "新增策略成功") return }) // 删除策略 r.DELETE("/policy", func(ctx *gin.Context) { sub := ctx.Query("user") obj := ctx.Query("path") act := ctx.Query("method") role := ctx.Query("group") if ok, err := e.RemovePolicy(sub, obj, act); !ok || err != nil { ctx.String(http.StatusOK, "删除策略失败") return } if role != "" { if ok, err := e.DeleteRoleForUser(sub, role); !ok || err != nil { ctx.String(http.StatusOK, "删除策略分组失败") return } } // 写入策略(保存到文件/数据库) e.SavePolicy() ctx.String(http.StatusOK, "删除策略成功") return }) // 策略列表 r.GET("/policy", func(ctx *gin.Context) { list := e.GetPolicy() ctx.JSON(http.StatusOK, list) return }) // 删除用户(同时删除【策略】和【分组】) r.DELETE("/user", func(ctx *gin.Context) { sub := ctx.Query("user") // 删除指定用户 if ok, err := e.DeleteUser(sub); !ok || err != nil { ctx.String(http.StatusOK, "删除用户失败") return } // 写入策略(保存到文件/数据库) e.SavePolicy() ctx.String(http.StatusOK, "删除用户成功") return }) r.GET("/test", func(ctx *gin.Context) { ctx.JSON(http.StatusOK, map[string]interface{}{ "sub": ctx.GetHeader("user"), "obj": ctx.Request.URL.Path, "act": ctx.Request.Method, }) return }) r.Run() }
基于数据库:
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) && r.obj == p.obj && r.act == p.act
main.go
:package main import ( "fmt" "github.com/casbin/casbin/v2" gormadapter "github.com/casbin/gorm-adapter/v3" "github.com/gin-gonic/gin" "gorm.io/driver/mysql" "gorm.io/gorm" "net/http" ) var e *casbin.Enforcer func init() { dsn := "root:123456@tcp(127.0.0.1:3306)/casbin_test?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic(err) } adapter, _ := gormadapter.NewAdapterByDB(db) e, err = casbin.NewEnforcer("model.conf", adapter) if err != nil { panic(err) } // 加载策略(从文件/数据库加载到内存) e.LoadPolicy() } func checkPermission(ctx *gin.Context) { sub := ctx.GetHeader("user") obj := ctx.Request.URL.Path act := ctx.Request.Method ok, err := e.Enforce(sub, obj, act) if err != nil { ctx.String(http.StatusInternalServerError, "内部服务器错误") ctx.Abort() } if !ok { ctx.String(http.StatusOK, "权限验证不通过") ctx.Abort() } fmt.Println("权限验证通过") ctx.Next() } func main() { r := gin.Default() r.Use(checkPermission) // 新增策略 r.PUT("/policy", func(ctx *gin.Context) { sub := ctx.Query("user") obj := ctx.Query("path") act := ctx.Query("method") role := ctx.Query("group") if ok, err := e.AddPolicy(sub, obj, act); !ok || err != nil { ctx.String(http.StatusOK, "新增策略失败") return } if role != "" { if ok, err := e.AddRoleForUser(sub, role); !ok || err != nil { ctx.String(http.StatusOK, "新增策略分组失败") return } } // 写入策略(保存到文件/数据库) e.SavePolicy() ctx.String(http.StatusOK, "新增策略成功") return }) // 删除策略 r.DELETE("/policy", func(ctx *gin.Context) { sub := ctx.Query("user") obj := ctx.Query("path") act := ctx.Query("method") role := ctx.Query("group") if ok, err := e.RemovePolicy(sub, obj, act); !ok || err != nil { ctx.String(http.StatusOK, "删除策略失败") return } if role != "" { if ok, err := e.DeleteRoleForUser(sub, role); !ok || err != nil { ctx.String(http.StatusOK, "删除策略分组失败") return } } // 写入策略(保存到文件/数据库) e.SavePolicy() ctx.String(http.StatusOK, "删除策略成功") return }) // 策略列表 r.GET("/policy", func(ctx *gin.Context) { list := e.GetPolicy() ctx.JSON(http.StatusOK, list) return }) // 删除用户(同时删除【策略】和【分组】) r.DELETE("/user", func(ctx *gin.Context) { sub := ctx.Query("user") // 删除指定用户 if ok, err := e.DeleteUser(sub); !ok || err != nil { ctx.String(http.StatusOK, "删除用户失败") return } // 写入策略(保存到文件/数据库) e.SavePolicy() ctx.String(http.StatusOK, "删除用户成功") return }) r.GET("/test", func(ctx *gin.Context) { ctx.JSON(http.StatusOK, map[string]interface{}{ "sub": ctx.GetHeader("user"), "obj": ctx.Request.URL.Path, "act": ctx.Request.Method, }) return }) r.Run() }
文档更新时间: 2024-04-20 10:57 作者:lee