Go语言通过Casbin配合MySQL和Gorm实现RBAC访问控制模型

Casbin 是一个强大的、开源的访问控制框架,支持多种访问控制模型(如 ACLRBACABAC 等)。它的核心功能是基于策略(policy)来决定是否允许某个操作,并通过模型(model)来定义如何进行这些决策。Casbin 通过角色、用户、权限等关系来管理访问权限。

首先我们需要导入以下几个包。

Go 复制代码
	"github.com/casbin/casbin/v2"
	gormadapter "github.com/casbin/gorm-adapter/v3"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"

然后编写model.conf文件

bash 复制代码
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act, eft

[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) || g(r.sub,"admin")

然后通过gorm来获取一个mysql数据库实例。

Go 复制代码
db, err := gorm.Open(mysql.Open("用户名:密码@tcp(主机地址:端口号)/数据库名"), &gorm.Config{})

然后通过数据库实例来获取一个casbin的gorm适配器,这个函数可以指定表名,因此可以用自己自定义的表,但是自定义的表,结构必须和casbin官方支持的数据表结构一样,如果不指定表名,那么casbin会自动检测数据库中是否有casbin_rule表或者casbin表(casbin_rule优先),如果有,就选择其中一张作为policy存放表,否则就会自动创建一张casbin_rule表。

Go 复制代码
a, err := gormadapter.NewAdapterByDBUseTableName(db, "", "casbin_rule")

casbin_rule的格式如下:

sql 复制代码
CREATE TABLE `casbin_rule` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `ptype` varchar(100) DEFAULT NULL,
  `v0` varchar(100) DEFAULT NULL,
  `v1` varchar(100) DEFAULT NULL,
  `v2` varchar(100) DEFAULT NULL,
  `v3` varchar(100) DEFAULT NULL,
  `v4` varchar(100) DEFAULT NULL,
  `v5` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_casbin_rule` (`ptype`,`v0`,`v1`,`v2`,`v3`,`v4`,`v5`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb3

需要注意的是,当casbin和gorm一起使用时,并不需要额外的结构体来绑定对应的数据表

然后通过适配器来获取鉴权执行对象。

Go 复制代码
e, err := casbin.NewEnforcer("model.conf", a)

调用鉴权执行对象的LoadPolicy函数,将casbin_rule里面数据加载到鉴权执行对象中,需要注意的是,当调用casbin.NewEnforcer函数后,其实它内部就自动调用了一次LoadPolicy函数了,所以如果调用casbin.NewEnforcer函数后,casbin_rule里面的数据没有发生改变(增加政策,增加分组),就可以不用再次调用LoadPolicy函数。

Go 复制代码
e.LoadPolicy()

接下来可以添加政策和分组,这里的政策格式必须和model.conf里面的格式一样

Go 复制代码
e.AddPolicy("admin","/user/adduser","POST","allow")
e.AddGroupingPolicy("amie", "admin")

这里可以直接添加到数据表中。

最后执行Enforce函数就可以验证一个用户是否具有某种权限了。

Go 复制代码
e.Enforce("amie", "/user/adduser", "POST", "allow")

casbin的进一步使用,可以将鉴权函数Enforce封装为一个函数接口,然后注册为gin路由的中间件函数,这样这个路由对应的所有请求在执行前,都会执行一次这个鉴权函数了,可以达到用户访问权限控制的目的。

相关推荐
风哥2号8 小时前
数据库教程FGMT27‑MySQL数据库基础知识与体系架构
数据库·mysql
风哥2号12 小时前
数据库教程FGMT43‑MySQL性能分析与优化调整
数据库·mysql
默 语15 小时前
Java新手入门:从零开始安装JDK并配置环境变量
java·开发语言·python·mysql·group by·1024程序员节·数据去重
用户30745969820715 小时前
MySQL EXPLAIN 零基础完全精通指南:从"看不懂"到"会优化"
mysql
这个DBA有点耶16 小时前
自增主键用尽了怎么办?INT溢出、在线迁移与预防策略全解析
数据库·mysql·代码规范
迷茫的大专生16 小时前
高可用总结
redis·mysql·nginx·高可用
迷茫的大专生18 小时前
服务器部署与 MySQL 运维学习笔记:从 Ansible 到高可用与性能优化
mysql·nginx·ansible·mysql优化·keepalive
Lyra_Infra18 小时前
从 MySQL 到达梦:一次信创隔离环境里的数据库迁移踩坑实录
数据库·后端·mysql
泡茶喝茶写代码19 小时前
量化数据开发实战系列(第 25 篇):基金基础接口实战:基金列表、ETF-LOF 分类、基金概况、净值数据
java·数据库·人工智能·python·mysql
worilb20 小时前
Win下使用同一套MySQL创建第二个独立实例
mysql