# go-zero-rbac **Repository Path**: chichengyu/go-zero-rbac ## Basic Information - **Project Name**: go-zero-rbac - **Description**: go-zero-rbac脚手架 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-14 - **Last Updated**: 2026-10-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # go_zero_rbac 基于 **go-zero** 微服务框架构建的企业级 RBAC(Role-Based Access Control)权限管理系统。 ## 技术栈 ### 基础设施 | 类别 | 技术选型 | 说明 | |------|----------|------| | 微服务框架 | go-zero v1.10.3 | 集服务发现、负载均衡、熔断、限流于一体 | | 数据库 ORM | go-zero sqlx(内置) | goctl model 自动生成带 Redis 缓存的 CRUD 代码 | | 权限管理 | Casbin v3 | RBAC 模型,纯内存鉴权,纳秒级响应 | | Casbin 适配器 | 自研 `database/sql` 适配器 | 零额外依赖,与 go-zero 技术栈天然一致 | | 认证 | golang-jwt v4 | JWT Token 签发与校验 | | 缓存 | Redis | go-zero sqlx read-through/write-through 缓存策略 | | 数据库 | MySQL 8.0 | 支持 PostgreSQL 切换 | | 服务通信 | gRPC(RPC 层) | 内网高效通信 | ### 封装工具依赖 | 工具包 | 依赖库 | 版本 | 说明 | 官网 | |--------|--------|------|------|------| | **xauth** | [golang-jwt/jwt](https://github.com/golang-jwt/jwt) | v4 | JWT Token 签发、解析、校验 | https://github.com/golang-jwt/jwt | | **xcasbin** | [casbin/casbin](https://github.com/casbin/casbin) | v3 | RBAC/ABAC 访问控制模型 | https://casbin.org/ | | **xcasbin** | Go 标准库 `database/sql` | — | 自研适配器,直接操作 MySQL 策略表 | https://pkg.go.dev/database/sql | | **xlock** | [go-redsync/redsync](https://github.com/go-redsync/redsync) | v4 | 多节点 Redlock 分布式锁算法 | https://github.com/go-redsync/redsync | | **xlock** | [redis/go-redis](https://github.com/redis/go-redis) | v9 | Redis 客户端(看门狗续期、Lua 脚本) | https://redis.uptrace.dev/ | | **xlock** | [google/uuid](https://github.com/google/uuid) | v1 | 锁标识 UUID 生成 | https://github.com/google/uuid | | **xcache** | [redis/go-redis](https://github.com/redis/go-redis) | v9 | Redis 缓存客户端(via go-zero) | https://redis.uptrace.dev/ | | **xresty** | [go-resty/resty](https://github.com/go-resty/resty) | v2 | HTTP 客户端(连接池、重试、重定向) | https://github.com/go-resty/resty | | **xerr** | [gRPC](https://grpc.io/) | v1 | gRPC 状态码转换 & 错误传递 | https://grpc.io/ | | **xutils** | [OpenTelemetry](https://opentelemetry.io/) | v1 | 链路追踪 traceId 提取 | https://opentelemetry.io/ | | **x* 通用** | [prometheus/client_golang](https://github.com/prometheus/client_golang) | v1 | 可观测性指标暴露(xlock/xcache/xresty) | https://prometheus.io/ | ## 项目结构 ``` go_zero_rbac/ ├── api/admin/ # HTTP 网关层(对外暴露) │ ├── admin.api # API 定义文件 │ ├── admin.go # 启动入口 │ ├── etc/ │ │ ├── admin-api.yaml # 配置文件 │ │ └── rbac_model.conf # Casbin RBAC 模型定义 │ └── internal/ │ ├── config/ # 配置结构体 │ ├── handler/ # 请求处理器(薄层,参数绑定) │ │ ├── routes.go # 路由注册 │ │ ├── user/ # 用户相关 handler │ │ └── role/ # 角色相关 handler │ ├── logic/ # 业务逻辑层 │ │ ├── user/ # 用户业务逻辑 │ │ └── role/ # 角色业务逻辑 │ ├── middleware/ │ │ ├── authmiddleware.go # JWT 认证中间件 │ │ └── permissionmiddleware.go # Casbin 鉴权中间件 │ ├── svc/ # 服务上下文(依赖注入) │ └── types/ # 请求/响应类型定义 ├── rpc/system/ # gRPC 服务层(对内) │ ├── system.proto # Protobuf 服务定义 │ ├── system.go # 启动入口 │ └── internal/ │ ├── config/ # RPC 配置 │ ├── logic/ # RPC 业务逻辑 │ ├── server/ # gRPC 服务注册 │ └── svc/ # 服务上下文 ├── model/ # 数据访问层(api 和 rpc 共享) │ ├── sysusermodel.go # 用户 model(自定义扩展) │ ├── sysusermodel_gen.go # 用户 model(goctl 生成,勿手动修改) │ ├── sysrolemodel.go # 角色 model │ ├── sysrolemodel_gen.go # 角色 model(生成) │ ├── syspermissionmodel.go # 权限 model │ ├── syspermissionmodel_gen.go # 权限 model(生成) │ ├── syslogmodel.go # 日志 model │ └── syslogmodel_gen.go # 日志 model(生成) ├── pkg/ # 公共库 │ ├── xauth/ # JWT 认证工具 │ │ └── Jwt.go │ ├── xcasbin/ # Casbin 封装 │ │ ├── adapter.go # 自研 database/sql 适配器 │ │ └── enforcer.go # Enforcer 封装 │ ├── xcode/ # 错误码定义 │ ├── xerr/ # 错误处理 │ ├── xresp/ # 统一响应格式 │ └── xutils/ # 工具函数 ├── db/ # 数据库脚本 │ └── go_zero_rbac.sql # 建表语句 + 种子数据 ├── go.mod └── go.sum ``` ## goctl 代码生成命令 ### API 层(admin 模块) API 定义文件按业务模块拆分:`admin.api` 主入口 + `user.api`(用户类型)+ `role.api`(角色类型),通过 `import` 聚合。 ```bash # 进入 admin 模块目录 cd api/admin # 一键生成所有 handler / logic / types / routes(goctl 自动解析 import 的子文件) goctl api go -api admin.api -dir . ``` 生成文件清单: | 文件/目录 | 来源 | 说明 | |-----------|------|------| | `internal/handler/routes.go` | goctl 生成 | 路由注册,自动包含 user/role 两组 handler | | `internal/handler/user/*.go` | goctl 生成 | 用户 handler(薄层,参数绑定后调用 logic) | | `internal/handler/role/*.go` | goctl 生成 | 角色 handler | | `internal/logic/user/*.go` | goctl 生成 | 用户业务逻辑骨架 | | `internal/logic/role/*.go` | goctl 生成 | 角色业务逻辑骨架 | | `internal/types/types.go` | goctl 生成 | 请求/响应类型定义(从 .api 文件生成) | ### RPC 层(system 模块) Proto 定义文件按业务模块拆分在 `proto/` 目录下:`user.proto`、`role.proto`、`permission.proto`,通过 `gen.go` 脚本合并后统一生成。 ```bash # 进入 system 模块目录 cd rpc/system # 方式一:gen.go 一键生成(推荐,自动合并 + 备份还原 + 保护业务代码) go run gen.go # 方式二:手动分步执行 # Step 1: 合并 proto(也由 gen.go 自动完成) # Step 2: 生成 Go 代码 goctl rpc protoc system.proto --go_out=. --go-grpc_out=. --zrpc_out=. -m ``` 生成文件清单: | 文件/目录 | 来源 | 说明 | |-----------|------|------| | `system.proto` | gen.go 合并 | 由 `proto/*.proto` 拼合,勿手动编辑 | | `system/*.pb.go` | protoc-gen-go | Protobuf 消息序列化代码 | | `system/*_grpc.pb.go` | protoc-gen-go-grpc | gRPC Client/Server 接口定义 | | `client/*/` | goctl 生成 | RPC 客户端调用封装(API 层通过它调用 RPC) | | `internal/logic/*/` | goctl 生成 | RPC 业务逻辑骨架(新增方法会追加文件) | | `internal/server/*/` | goctl 生成 | gRPC 服务注册(新增 service 自动追加) | | `internal/svc/` | 手动维护(gen.go 保护) | 服务上下文,不会被覆盖 | | `internal/config/` | 手动维护(gen.go 保护) | RPC 配置结构体,不会被覆盖 | | `etc/` | 手动维护(gen.go 保护) | 配置文件目录,不会被覆盖 | > **gen.go 安全机制**:执行前自动备份 `internal/`、`etc/`、`system.go` 到 `.gen_backup/`,goctl 生成后自动还原,业务代码零风险。如果 goctl 执行崩溃,defer 机制也会自动从备份恢复。 ### Model 层(数据库 CRUD) Model 代码使用 goctl 从 MySQL 数据表或 DDL 文件生成,采用**双文件继承模式**:`xxx_gen.go`(goctl 生成,勿手动编辑)+ `xxx.go`(开发者维护,继承 _gen 方法 + 自定义扩展)。 ```bash # 进入 model 目录 cd model # 方式一:从 DDL 文件生成(推荐,可离线执行) # 注意:--src 是包含 CREATE TABLE 的 SQL 文件路径 goctl model mysql ddl -src "../db/go_zero_rbac.sql" -dir . -cache # 方式二:从数据库直接生成(需 MySQL 可连接) goctl model mysql datasource -url "root:123456@tcp(127.0.0.1:3306)/go_rbac_admin" -table "sys_user,sys_role,sys_permission,sys_log" -dir . -cache ``` | 参数 | 说明 | |------|------| | `-src` | DDL SQL 文件路径(方式一) | | `-url` | MySQL 连接 DSN(方式二) | | `-table` | 指定表名,逗号分隔(方式二) | | `-dir` | 输出目录(`.` 表示当前目录) | | `-cache` | 生成带 Redis 缓存的 CRUD 代码(read-through/write-through) | 生成文件: | 文件 | 来源 | 说明 | |------|------|------| | `sysusermodel_gen.go` | goctl 生成 → **勿手动编辑** | Insert/FindOne/Update/Delete + Redis 缓存 | | `sysusermodel.go` | 首次生成 → 手动维护 | 自定义方法扩展(如 FindByUsername) | | `sysrolemodel_gen.go` | goctl 生成 | 角色 CRUD,同上 | | `syspermissionmodel_gen.go` | goctl 生成 | 权限 CRUD,同上 | | `syslogmodel_gen.go` | goctl 生成 | 日志 CRUD,同上 | > **双文件模式**:重新生成时 goctl 只会覆盖 `_gen.go` 文件,你的 `xxx.go` 自定义方法不会被影响。 ## 架构亮点 ### 1. 纯 database/sql 的 Casbin 适配器(行业少见) 市面上 go-zero + Casbin 项目 **90% 以上直接引入 gorm-adapter**,导致一个项目同时存在 go-zero sqlx 和 GORM 两套 ORM。本项目自研了 `pkg/xcasbin/adapter.go`,**157 行代码**实现完整的 `persist.Adapter` 接口: - **零额外依赖**:只依赖 Go 标准库 `database/sql`,与 go-zero sqlx 底层完全一致 - **连接池管理**:`SetMaxOpenConns(10)` + `SetMaxIdleConns(5)` + `SetConnMaxLifetime(5min)` - **并发安全**:`sql.DB` 天然协程安全 ### 2. 完整中间件链 ``` HTTP Request │ ▼ ┌──────────────────────┐ │ AuthMiddleware │ ← JWT Token 解析,注入 userId 到 Context │ 中间件顺序: 第 1 层 │ └──────────┬───────────┘ ▼ ┌──────────────────────┐ │ PermissionMiddleware │ ← Casbin Enforce(userId, path, method) │ 中间件顺序: 第 2 层 │ 纯内存匹配,200-400 纳秒/次 └──────────┬───────────┘ ▼ ┌──────────────────────┐ │ Business Handler │ ← 执行业务逻辑 └──────────────────────┘ ``` ### 3. Casbin RBAC 模型 ``` [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) && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act) ``` Casbin 策略示例(`casbin_rule` 表): | ptype | v0 | v1 | v2 | 含义 | |-------|----|----|----|------| | g | user_001 | role_admin | | 用户 user_001 属于 admin 角色 | | p | role_admin | /api/user/* | GET | admin 角色可查看用户 | | p | role_admin | /api/role | POST | admin 角色可创建角色 | ### 4. Model 层设计模式 goctl 生成的代码采用**双文件继承模式**,支持自定义扩展且不会被重新生成覆盖: ``` sysusermodel_gen.go ← goctl 生成,含 Insert/FindOne/Update/Delete sysusermodel.go ← 开发者维护,继承 _gen 方法 + 自定义方法 // 自定义方法示例 func (m *customSysUserModel) FindByUsername(ctx context.Context, username string) (*SysUser, error) { // 手写 SQL,完全可控 } ``` ## 快速开始 ### 环境要求 | 组件 | 版本 | |------|------| | Go | >= 1.25 | | MySQL | >= 8.0 | | Redis | >= 6.0 | | goctl | >= 1.10 | ### 1. 初始化数据库 ```bash # 导入 SQL 建表脚本和数据 mysql -u root -p < db/go_zero_rbac.sql ``` ### 2. 修改配置文件 `api/admin/etc/admin-api.yaml`: ```yaml Name: admin-api Host: 0.0.0.0 Port: 8888 Auth: AccessSecret: "your-jwt-secret-key" # JWT 签名密钥,生产环境请更换 AccessExpire: 86400 # Token 过期时间(秒) CasbinDB: DSN: "root:password@tcp(127.0.0.1:3306)/go_rbac_admin?charset=utf8mb4&parseTime=true&loc=Local" # Redis 缓存(model 层使用) Cache: - Host: 127.0.0.1:6379 Pass: "" ``` ### 3. 安装依赖并启动 ```bash # 安装依赖 go mod tidy # 启动 admin-api 服务 go run api/admin/admin.go ``` 服务启动后访问 `http://localhost:8888`。 ### 4. 接口测试 ```bash # 1. 登录获取 Token curl -X POST http://localhost:8888/admin/user/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"123456"}' # 2. 携带 Token 访问受保护接口 curl http://localhost:8888/admin/user/list \ -H "Authorization: Bearer " # 3. 权限不足会返回 403 ``` ## 开发指南 ### 生成 Model 层代码 ```bash # 从 DDL 文件生成(带 Redis 缓存) goctl model mysql ddl -src="./db/*.sql" -dir="./model" -c=true # 从数据源直连生成 goctl model mysql datasource -url="root:pass@tcp(127.0.0.1:3306)/go_rbac_admin" -table="sys_user" -dir="./model" -c=true ``` ### 生成 API 层代码 ```bash # 在 api/admin/ 目录下 goctl api go -api admin.api -dir . ``` ### 生成 RPC 层代码(gen.go 代码生成器) 每个 RPC 模块目录下都有一个 `gen.go` 通用代码生成器,**一行命令完成 proto 合并 → protobuf 编译 → 代码生成 → 业务代码保护 → 自动修复**。 #### 核心特性 | 特性 | 说明 | |------|------| | **通用性** | 复制到任意模块目录直接执行,模块名/路径自动检测,无需手动改代码 | | **多 proto 合并** | proto/ 下多个 `.proto` 文件自动合并为一个 `{模块}.proto` | | **业务代码零风险** | 执行前自动备份 `internal/`、`etc/`、`{模块}.go`,执行后完整还原 | | **备份轮转** | 保留两代备份(`.gen_backup` / `.gen_backup.old`),出问题可回滚 | | **崩溃恢复** | goctl 崩溃时 defer 自动从备份紧急还原 | | **自动修复** | 自动补全 client type alias、入口文件缺失的 import/注册/健康检查 | | **不写死** | import 动态管理,用户可自由增删标准 import,只自动补 service 相关和健康检查 | #### 使用方式 ```bash # === 已有模块:编辑 proto 后重新生成 === cd rpc/system go run gen.go # === 新模块(如 order): 复制脚本后执行 === mkdir rpc/order cp rpc/system/gen.go rpc/order/ cd rpc/order go run gen.go # 首次:自动创建 proto/ 目录 + 模板文件 # 编辑 proto/_template.proto → 重命名为 proto/order.proto 等 go run gen.go # 再次:合并生成 + goctl 编译 ``` #### 执行流程 ``` go run gen.go 📦 [1/5] 合并 proto 文件 → {模块}.proto 💾 [2/5] 备份用户业务代码 → .gen_backup/ (internal + etc + {模块}.go) 🔨 [3/5] 编译 protobuf (goctl) → *.pb.go + client/ + internal/ ♻️ [4/5] 还原用户业务代码 → 从 .gen_backup/ 还原 🔧 [5/5] 自动修复生成文件 → client alias + 入口文件补充 ``` #### 新增 RPC 方法 ```bash # 1. 编辑 proto 文件(如 proto/user.proto),添加新的 rpc # 2. 重新执行 go run gen.go # 3. 新的 logic 骨架在 internal/logic/ 下,补充业务逻辑即可 ``` #### 手动还原备份 ```bash go run gen.go -restore # 从最新备份还原所有业务代码 ``` #### 备份目录说明 ``` rpc/system/ ├── .gen_backup/ ← 最新备份(每次 gen 前自动创建) ├── .gen_backup.old/ ← 上一次备份(保留备用) ├── internal/ ← gen 后从备份还原,你的代码不改 ├── etc/ ← gen 后从备份还原 ├── system.go ← gen 后从备份还原 + 自动补充缺失项 ├── system.proto ← gen 自动生成(勿手动编辑) ├── system/*.pb.go ← gen 自动生成(勿手动编辑) ├── client/ ← gen 自动生成(type alias 已补全) └── gen.go ← 代码生成器脚本 ``` #### proto 文件模板 每个 `.proto` 文件必须包含以下三行头(gen.go 首次执行时会自动生成模板并提示): ```protobuf syntax = "proto3"; package system; // 与模块名一致 option go_package = "./system"; // 与模块名一致 message LoginRequest { string username = 1; string password = 2; } service UserService { rpc Login(LoginRequest) returns (LoginResponse); } ``` ### xcasbin 包 API ```go // 权限校验 enforcer.Enforce(userId, path, method) // 角色管理 enforcer.AddRoleForUser(userId, roleId) enforcer.DeleteRoleForUser(userId, roleId) enforcer.GetRolesForUser(userId) // 权限管理 enforcer.AddPermissionForUser(roleId, path, method) enforcer.DeletePermissionForUser(roleId, path, method) enforcer.GetPermissionsForUser(userId) ``` ## 权限策略流转 ``` 启动时: adapter 直连 MySQL → LoadPolicy() → 所有策略加载到 Casbin 内存 运行时鉴权: Enforce() → 纯内存匹配 → 200-400 纳秒(不查库、不走 RPC) 策略变更: 管理员操作 → API Logic → RPC → 写 MySQL → 通知重载策略 ``` ## 微服拆分建议 当前阶段为单服务架构。后续演进路径: ``` 单服务(现在): api/admin/ ← HTTP + 业务逻辑都在这里 微服务(将来): api/admin/ ← HTTP 网关 + 中间件(认证 + 鉴权) │ gRPC ▼ rpc/system/ ← 核心业务逻辑(用户、角色、权限、菜单) │ ▼ model/ ← 数据访问层 ``` --- ## License MIT