Casbin + Gin + Gorm 学习探索
Casbin 是一个强大的,开源的访问控制框架,权限管理机制支持多种访问控制模型; 并且支持多种编程语言;
文档地址:https://casbin.org/docs/zh-CN/overview
Gin Golang 的 Web 框架,短小精悍
文档地址: https://gin-gonic.com/docs/
Gorm Golang 的 ORM 框架
文档地址:http://gorm.book.jasperxu.com/
今天我们要学习的是如何通过Casbin 来控制开发的 API 访问权限
##### Casbin 工作原理
访问控制模型被抽象为PERM(Policy,Effect,Request,Matcher) 的一个文件,如果切换项目的授权机制只用修改文件即可;
Policy: 定义权限的规则
Effect: 定义组合多个Policy 后是允许还是拒绝(allow/deny)
Request: 访问的请求,可以理解为谁想访问什么资源
Matcher:判断Request 是否满足Policy ,返回true或false
##### 在使用Casbin 控制后台接口时使用以下模型
[request_definition]
r = sub, obj, act
# 请求的规则
# r 是规则的名称,sub 为请求的实体,obj 为资源的名称, act 为请求的实际操作动作
[policy_definition]
p = sub, obj, act
# 策略的规则
# 同请求
[role_definition]
g = _, _
# 角色的定义
# g 角色的名称,第一个位置为用户,第二个位置为角色,第三个位置为域(在多租户场景下使用)
[policy_effect]
e = some(where (p.eft == allow))
# 任意一条 policy rule 满足, 则最终结果为 allow
[matchers]
m = g(r.sub, p.sub) == true \
&& keyMatch2(r.obj, p.obj) == true \
&& regexMatch(r.act, p.act) == true \
|| r.sub == "root"
# 前三个用来匹配上面定义的请求的规则, 最后一个或条件为:如果实体是root 直接通过, 不验证权限
在理解了Casbin 的工作原理后,实际写代码测试一下
需要使用的外部包
go get github.com/casbin/casbin Casbin 官方库
go get github.com/casbin/gorm-adapter Casbin 插件,用来将规则和策略保存到数据库中
go get github.com/gin-gonic/gin Go Web 框架
go get github.com/go-sql-driver/mysql Go MySQL 驱动
go get github.com/jinzhu/gorm Go ORMpackage mainimport ( "fmt" "github.com/casbin/casbin"
"github.com/casbin/gorm-adapter"
"github.com/gin-gonic/gin"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
)
// 统一响应结构体
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
} var O *gorm.DB
var PO *gormadapter.Adapter
var Enforcer *casbin.Enforcer
func ping(c *gin.Context) {
var response Response
response.Code = 0
response.Message = "success"
response.Data = ""
c.JSON(200, response)
return
}
// 数据库连接及角色规则的初始化
func connect() {
dsn := "xxx:xxx@(xxxx:3xx6)/goapp?charset=utf8&parseTime=True&loc=Local"
var err error
O, err = gorm.Open("mysql", dsn)
if err != nil {
fmt.Println("connect DB error")
panic(err)
}
// 将数据库连接同步给插件, 插件用来操作数据库
PO = gormadapter.NewAdapterByDB(O)
// 这里也可以使用原生字符串方式
//
Enforcer = casbin.NewEnforcer("./auth_model.conf", PO)
// 开启权限认证日志
Enforcer.EnableLog(true)
// 加载数据库中的策略
err = Enforcer.LoadPolicy()
if err != nil {
fmt.Println("loadPolicy error")
panic(err)
}
// 创建一个角色,并赋于权限
// admin 这个角色可以访问GET 方式访问 /api/v2/ping
res := Enforcer.AddPolicy("admin","/api/v2/ping","GET")
if !res {
fmt.Println("policy is exist")
} else {
fmt.Println("policy is not exist, adding")
}
// 将 test 用户加入一个角色中
Enforcer.AddRoleForUser("test","root")
Enforcer.AddRoleForUser("tom","admin")
// 请看规则中如果用户名为 root 则不受限制
}
func main() {
defer O.Close()
connect()
g := gin.Default()
// 这里的接口没有使用权限认证中间件
version1 := g.Group("/api/v1")
{
version1.GET("/ping", ping) // 这个是通用的接口
}
// 接口使用权限认证中间件
version2 := g.Group("/api/v2", CasbinMiddleWare)
{
version2.GET("/ping", ping)
}
_ = g.Run(":8099")
} // casbin middleware 权限认证中间件
func CasbinMiddleWare(c *gin.Context) {
var userName string
userName = c.GetHeader("userName")
if userName == "" {
fmt.Println("headers invalid")
c.JSON(200, gin.H{
"code": 401,
"message": "Unauthorized",
"data": "",
})
c.Abort()
return
}
// 请求的path
p := c.Request.URL.Path
// 请求的方法
m := c.Request.Method
// 这里认证
res,err := Enforcer.EnforceSafe(userName,p,m)
// 这个 HasPermissionForUser 跟上面的有什么区别
// EnforceSafe 会验证角色的相关的权限
// 而 HasPermissionForUser 只验证用户是否有权限
//res = Enforcer.HasPermissionForUser(userName,p,m)
if err != nil {
fmt.Println("no permission ")
fmt.Println(err)
c.JSON(200, gin.H{
"code": 401,
"message": "Unauthorized",
"data": "",
})
c.Abort()
return
}
if !res {
fmt.Println("permission check failed")
c.JSON(200, gin.H{
"code": 401,
"message": "Unauthorized",
"data": "",
})
c.Abort()
return
}
c.Next()
}
程序运行后数据库数据为

p 代表的是策略 admin 角色可以使用GET 访问 /api/v2/ping
g 代表的是角色 test 用户在root 角色中
tom 在admin 角色中
所以在测试时请求头
userName = root 有正常响应 (这里不会到数据库验证,策略最后一条)
userName = tom 正常响应 (tom 有admin 角色 , 所以验证通过)
userName = role_admin 正常响应 (参考这里:https://casbin.org/docs/zh-CN/rbac , 正常情况下用户名和角色名称不应该一样)
userName = *** 都无法通过认证
########
最后, 一般的后台开发不会这样设计, 后面继续学习,理解 Casbin 工作原理,为以后开发打下基础;
Casbin + Gin + Gorm 学习探索的更多相关文章
- [开源]Gin + GORM + Casbin+vue-element-admin 实现权限管理系统(golang)
简析 基于 Gin + GORM + Casbin + vue-element-admin 实现的权限管理系统. 基于Casbin 实现RBAC权限管理. 前端实现: vue-element-admi ...
- 基于Gin+Gorm框架搭建MVC模式的Go语言后端系统
文/朱季谦 环境准备:安装Gin与Gorm 本文搭建准备环境:Gin+Gorm+MySql. Gin是Go语言的一套WEB框架,在学习一种陌生语言的陌生框架,最好的方式,就是用我们熟悉的思维去学.作为 ...
- App自动化测试框架学习探索--从零开始设计
App自动化测试框架学习探索--从零开始设计---持续更新中,敬请关注 1 批量执行app自动化测试使用多线程设计思路: 1)并发级别选择用methods 2)采用@Test多线程,数据提供类dp单线 ...
- 使用go, gin, gorm编写一个简单的curd的api接口
go 是一门非常灵活的语言,既具有静态语言的高性能,又有动态语言的开发速度快的优点,语法也比较简单,下面是通过简单的代码实现了一个简单的增删改查 api 接口 hello world 常规版 新建 d ...
- Go orm框架gorm学习
之前咱们学习过原生的Go连接MYSQL的方法,使用Go自带的"database/sql"数据库连接api,"github.com/go-sql-driver/mysql& ...
- [Golang] Gin框架学习笔记
0x0 Gin简介 1.Gin 是什么? Gin 是一个用 Go (Golang) 编写的 HTTP web 框架. 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httpr ...
- Golang gin框架学习
今天开始学习gin框架,在Github上找的示例的go-gin-example, 进度 日期 进展 疑惑 进展 1.30 下拉代码,初步了解gin的介绍.搭建 .mod文件 module原理.使用方法 ...
- gin+gorm 用户服务
package main import ( "fmt" "github.com/gin-gonic/gin" "github.com/jinzhu/g ...
- Android学习探索之Java 8 在Android 开发中的应用
前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...
随机推荐
- 【LeetCode】49. Group Anagrams 解题报告(Python & Java & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 排序+hash 日期 题目地址:https://le ...
- 1036 - A Refining Company
1036 - A Refining Company PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 32 ...
- Codeforces 1073C:Vasya and Robot(二分)
C. Vasya and Robot time limit per test: 1 secondmemory limit per test: 256 megabytesinput: standard ...
- 【嵌入式】arduino常用函数
IO函数 设置引脚 pinMode(0-13,INPUT/OUTPUT/INPUT_PULLUP) 设置输出 digitalWrite(0-13,HIGH/LOW) 读取引脚 digitalRead( ...
- 「算法笔记」Splay
一.简介 Splay(伸展树)是平衡树中的一种.它通过不断将某个节点旋转到根节点的位置,使整棵树仍满足 BST 的性质,并且保持平衡而不至于退化为链. 频繁访问的节点会被移动到离根节点较近的位置,进而 ...
- 如何基于LSM-tree架构实现一写多读
一 前言 PolarDB是阿里巴巴自研的新一代云原生关系型数据库,在存储计算分离架构下,利用了软硬件结合的优势,为用户提供具备极致弹性.海量存储.高性能.低成本的数据库服务.X-Engine是阿里巴 ...
- 解决ubuntu突然无法联网问题
一.问题描述 今天使用笔记本远程办公的时候,突然电脑无法联网了,使用chrome浏览器访问网页出现如下错误 This site can't be reachedwww.baidu.com's serv ...
- Capstone CS5213|HDMI转VGA|CS5213设计参考电路
Capstone CS5213是一款HDMI到VGA转换器结合了HDMI输入接口和模拟RGB DAC输出且带支持片上音频数模转换器.CS5213芯片设计简单,整体芯片尺寸精悍,外围电路集成优化度较高, ...
- Java初学者作业——学生成绩等级流程图练习
返回本章节 返回作业目录 在Word 中编写算法实现学生成绩等级的输出,并绘制对应算法的流程图. 功能要求:输入学生成绩,输出对应成绩等级,输出规则如下: 学生成绩区间 对应成绩等级 [90,100] ...
- .Net Core 3.1 WebApi使用Swagger生成Api文档
用swagger生成Api文档 1.安装Swashbuckle.AspNetCore 右键单击"解决方案资源管理器" > "管理 NuGet 包"中的项目 ...