Go 中最强大的权限控制库Casbin权限控制它决定了 “谁能访问什么资源能做什么操作”。Casbin是一个强大的、高效的开源访问控制框架支持 ACL、RBAC、ABAC 等多种经典访问控制模型通过配置文件即可灵活定义权限规则同时支持策略的动态管理和持久化存储。概念作用说明Model模型定义权限控制的逻辑用 CONF 格式的文件或字符串编写定义 “请求是什么、策略是什么、如何匹配、结果是什么”Policy策略定义具体的权限规则可以存储在文件、数据库中定义 “谁用户 / 角色能对什么资源做什么操作”Adapter适配器负责策略的存储和加载支持文件、MySQL、PostgreSQL、Redis、MongoDB 等多种存储方式Enforcer执行器Casbin 的核心组件加载 Model 和 Policy提供权限判断、策略管理等核心 APIACL访问控制列表ACL 是最简单的访问控制模型直接定义 “用户 → 资源 → 操作” 的权限关系适合小型项目或简单的权限场景。编写 Model 文件model.confModel 文件定义了权限控制的逻辑Casbin 通过它来理解如何判断权限。[request_definition] # 定义请求的格式r [主体(sub), 客体(obj), 动作(act)] # sub用户/角色obj资源act操作如 read、write r sub, obj, act [policy_definition] # 定义策略的格式p [主体(sub), 客体(obj), 动作(act)] p sub, obj, act [policy_effect] # 定义策略效果e some(where (p.eft allow)) # 意思是只要有一条策略匹配且效果为 allow就允许访问 e some(where (p.eft allow)) [matchers] # 定义匹配规则m r.sub p.sub r.obj p.obj r.act p.act # 意思是请求的 sub、obj、act 必须和策略完全一致才匹配 m r.sub p.sub r.obj p.obj r.act p.act编写 Policy 文件policy.csvPolicy 文件定义了具体的权限规则用 CSV 格式存储。# p, 主体, 客体, 动作 p, zhangsan, /api/user, read p, zhangsan, /api/user, write p, lisi, /api/article, read上面的策略表示zhangsan可以对/api/user资源进行read和write操作lisi可以对/api/article资源进行read操作初始化 Enforcer加载 Model 文件和 Policy 文件// 参数 1Model 文件路径// 参数 2Policy 文件路径e,err:casbin.NewEnforcer(./model.conf,./policy.csv)iferr!nil{fmt.Printf(初始化 Enforcer 失败%v\n,err)return}casbin.NewEnforcer(modelPath, policyPath)初始化 Enforcer加载 Model 和 Policy。权限判断使用 Enforce 方法// 参数顺序sub, obj, act和 Model 中 r 的定义一致// 场景 1zhangsan 读取 /api/userok,err:e.Enforce(zhangsan,/api/user,read)iferr!nil{fmt.Printf(权限判断失败%v\n,err)return}ifok{fmt.Println(zhangsan 允许读取 /api/user)}else{fmt.Println(zhangsan 不允许读取 /api/user)}// 场景 2lisi 写入 /api/article策略中没有这条应该拒绝ok,_e.Enforce(lisi,/api/article,write)ifok{fmt.Println(lisi 允许写入 /api/article)}else{fmt.Println(lisi 不允许写入 /api/article)}e.Enforce(sub, obj, act)核心权限判断方法参数顺序必须和 Model 中r的定义一致返回bool表示是否允许访问。RBAC基于角色的访问控制RBAC 是企业开发中最常用的权限模型它通过 “角色” 作为中间层将用户与权限解耦用户 → 角色 → 权限大大简化了权限管理比如给用户分配角色即可获得该角色的所有权限无需逐个分配。编写 RBAC Model 文件rbac_model.confRBAC 模型在 ACL 的基础上增加了角色定义g和角色继承。[request_definition] r sub, obj, act [policy_definition] p sub, obj, act [role_definition] # 定义角色关系g [用户, 角色] # 表示“用户属于某个角色” g _, _ [policy_effect] e some(where (p.eft allow)) [matchers] # 匹配规则g(r.sub, p.sub) 表示“请求的用户属于策略中的角色” # 或者请求的用户直接等于策略中的主体支持用户直接分配权限 m g(r.sub, p.sub) r.obj p.obj r.act p.act编写 RBAC Policy 文件rbac_policy.csv角色权限admin可以对/api/user和/api/article进行read和writeeditor可以对/api/article进行read和writeviewer只能对/api/article进行read用户角色zhangsan是adminlisi是editorwangwu是viewer# 1. 角色权限策略p, 角色, 资源, 动作 p, admin, /api/user, read p, admin, /api/user, write p, admin, /api/article, read p, admin, /api/article, write p, editor, /api/article, read p, editor, /api/article, write p, viewer, /api/article, read # 2. 用户角色策略g, 用户, 角色 g, zhangsan, admin g, lisi, editor g, wangwu, viewer动态管理用户角色// 给 wangwu 添加 editor 角色现在 wangwu 是 viewer editoradded,err:e.AddRoleForUser(wangwu,editor)ifadded{// 保存策略到文件生产环境用数据库适配器自动保存e.SavePolicy()}// 现在 wangwu 应该允许写入 /api/article 了ok,_e.Enforce(wangwu,/api/article,write)// 删除 wangwu 的 viewer 角色removed,err:e.DeleteRoleForUser(wangwu,viewer)ifremoved{e.SavePolicy()}动态管理权限// 给 editor 角色添加 /api/user 的 read 权限added,erre.AddPolicy(editor,/api/user,read)ifadded{e.SavePolicy()}// 现在 lisieditor应该允许读取 /api/user 了ok,_e.Enforce(lisi,/api/user,read)API作用e.AddRoleForUser(user, role)给用户添加角色e.DeleteRoleForUser(user, role)删除用户的角色e.GetRolesForUser(user)获取用户的所有角色e.GetUsersForRole(role)获取拥有该角色的所有用户e.AddPolicy(sub, obj, act)添加权限策略e.DeletePolicy(sub, obj, act)删除权限策略e.SavePolicy()保存策略到存储文件 / 数据库RBAC with Domains多租户 / 多部门如果你的系统是多租户如 SaaS 平台或多部门的需要隔离不同租户 / 部门的权限Casbin 支持 RBAC with Domains 模型轻松实现权限隔离。在request_definition和matchers中增加dom域 / 租户字段[request_definition] r sub, dom, obj, act [policy_definition] p sub, dom, obj, act [role_definition] g _, _, _ [policy_effect] e some(where (p.eft allow)) [matchers] m g(r.sub, r.dom, p.sub, p.dom) r.dom p.dom r.obj p.obj r.act p.act权限判断和角色管理时需要增加dom参数// 权限判断sub, dom, obj, acte.Enforce(zhangsan,tenant1,/api/user,read)// 给用户添加租户下的角色e.AddRoleForUserInDomain(zhangsan,admin,tenant1)数据库适配器在开发环境中我们可以用文件存储 Policy但在生产环境中通常需要用数据库存储 Policy方便动态管理和持久化。Casbin 提供了丰富的数据库适配器这里以最常用的GORM Adapter配合 MySQL为例。// 1. 连接 MySQL 数据库dsn:root:your_passwordtcp(127.0.0.1:3306)/casbin_demo?charsetutf8mb4parseTimeTruelocLocaldb,err:gorm.Open(mysql.Open(dsn),gorm.Config{})// 2. 初始化 GORM Adapter// 参数 1GORM DB 实例// 参数 2是否自动迁移创建 casbin_rule 表a,err:gormadapter.NewAdapterByDB(db)// 3. 初始化 Enforcer加载 Model 文件和数据库 Adaptere,err:casbin.NewEnforcer(./rbac_model.conf,a)// 4. 初始化策略仅第一次运行时执行后续可注释// 添加角色权限e.AddPolicy(admin,/api/user,read)e.AddPolicy(admin,/api/user,write)// 添加用户角色e.AddRoleForUser(zhangsan,admin)// 保存策略到数据库e.SavePolicy()// 5. 权限判断ok,_:e.Enforce(zhangsan,/api/user,write)// 6. 动态修改策略自动同步到数据库e.AddRoleForUser(wangwu,editor)ok,_e.Enforce(wangwu,/api/article,write)自动同步使用数据库 Adapter 后调用AddPolicy、AddRoleForUser等 API 时策略会自动同步到数据库无需手动调用SavePolicy()部分 Adapter 需要GORM Adapter 自动同步。持久化策略存储在数据库中服务重启后不会丢失。动态管理可以通过数据库直接管理策略或通过后台管理界面调用 Casbin API 管理。最佳实践Model 设计Model 文件独立存储将 Model 文件放在项目的config目录下不要硬编码在代码里。从简单到复杂优先使用 RBAC只有在需要属性级权限控制时才用 ABAC。合理使用通配符Casbin 支持*通配符如p, admin, *, *表示 admin 可以访问所有资源的所有操作但要谨慎使用避免权限过大。策略管理生产环境用数据库 Adapter不要用文件存储 Policy推荐用 GORM Adapter 或 Redis Adapter。策略缓存Casbin 内置了策略缓存高并发场景下可大幅提升性能默认开启。定期备份策略定期备份数据库中的策略表防止误操作导致策略丢失。性能优化使用 EnforceContext高并发场景下使用EnforceContext替代Enforce支持上下文传递和超时控制。批量权限判断使用BatchEnforce进行批量权限判断性能更高。合理设计索引如果使用数据库 Adapter确保casbin_rule表有合理的索引GORM Adapter 会自动创建。安全注意事项不要在策略中存储敏感信息策略仅存储权限规则不要存储密码、密钥等敏感信息。最小权限原则给用户和角色分配最小必要的权限避免权限过大。权限验证前置在 Gin/Echo 等框架的中间件中统一进行权限验证避免每个接口都写权限判断代码。