9.4 KiB
VBase 后端架构设计文档
1. 概览
VBase 是一个基于 Golang 的高性能后端基础框架,旨在提供一套标准化的用户管理、组织架构(多租户)、权限控制(RBAC)和 OAuth2 认证服务。项目采用分层架构设计,基于 vigo 框架构建,强调代码的可维护性、扩展性和安全性。
2. 技术栈
- 语言: Golang 1.22+
- Web 框架: vigo (基于洋葱模型的高性能框架)
- ORM: GORM (支持 MySQL, PostgreSQL, SQLite 等)
- 配置管理:
cfg包 (支持环境变量、配置文件) - 认证: JWT (JSON Web Token) + OAuth2
- 数据库: 关系型数据库 (MySQL/PostgreSQL)
3. 系统架构
项目遵循经典的洋葱模型和分层架构:
Request -> [Global Middlewares] -> [Router] -> [Group Middlewares] -> [Handler] -> [Service/Logic] -> [Model/DAO] -> Database
|
Response <- [Global After Middleware] <------------------------------------+
3.1 目录结构
/
├── api/ # API 接口层 (路由定义、请求处理)
│ ├── auth/ # 认证相关接口 (登录、注册、刷新Token)
│ ├── oauth/ # OAuth2 Provider 接口
│ ├── org/ # 组织/租户管理接口
│ ├── user/ # 用户管理接口
│ └── init.go # 路由聚合与全局中间件配置
├── auth/ # 核心权限控制模块 (RBAC 实现)
├── cfg/ # 配置与基础设施 (DB, Redis, Log)
├── models/ # 数据模型定义 (GORM 结构体)
├── libs/ # 通用工具库
├── cli/ # 命令行入口
└── doc/ # 文档
4. 核心模块设计
4.1 认证与授权 (Auth Module)
Auth 模块是系统的核心安全组件,实现了基于角色的访问控制 (RBAC) 和资源级权限管理。
4.1.1 核心概念
- Permission (权限): 最小粒度的操作许可,格式严格遵循
resource:action或app:resource:action。- 示例:
user:read,org:create,oauth-client:delete - 约束: 资源标识符 (
resource) 只能包含字母、数字、下划线和连字符,严禁包含冒号,以避免解析歧义。
- 示例:
- Role (角色): 权限的集合。系统预设角色包括
admin(管理员) 和user(普通用户)。 - UserRole (用户-角色关联): 用户在特定组织 (
OrgID) 下拥有的角色。 - Policy (策略): 定义角色拥有的权限列表。
4.1.2 权限验证机制
系统提供 auth.Auth 接口和 VBaseAuth 实例,支持多种验证方式:
- 基础权限:
Perm("resource:action")- 检查用户是否拥有指定权限。 - 资源所有者:
PermWithOwner("resource:action", "owner_id_key")- 如果用户是资源所有者则放行,否则检查权限。 - 特定资源:
PermOnResource("resource:action", "resource_id_key")- 检查用户对特定资源实例的权限。 - 组合权限:
PermAny,PermAll- 支持“任一”或“所有”权限的逻辑组合。 - 通配符支持: 支持
*通配符,如app:resource:*匹配该资源下的所有操作。
4.1.3 中间件流程
- AuthMiddleware: 解析 JWT Token,提取 UserID 和 OrgID,注入到请求上下文 (
vigo.X)。 - PermMiddleware: 在业务 Handler 执行前拦截请求,调用
CheckPermission进行鉴权。
4.2 用户体系 (User Module)
- User: 核心用户实体,包含基本信息 (昵称、头像、邮箱等)。
- Identity: 认证信息表,支持多种登录方式 (密码、OAuth、验证码等) 关联到同一用户。
- Session: 用户会话管理,用于记录登录状态和刷新 Token。
4.3 组织架构 (Org Module)
支持多租户模型的组织管理:
- Org: 组织/团队实体。
- OrgMember: 组织成员关系表,记录用户在组织内的角色 (
RoleIDs)。 - Context 隔离: 所有数据操作通过
OrgID进行逻辑隔离 (在auth.AuthMiddleware中解析并注入)。
4.4 OAuth2 服务 (OAuth Module)
实现了完整的 OAuth2 Provider 功能,支持第三方应用接入:
- Client: 第三方应用注册信息 (ClientID, ClientSecret)。
- AuthorizationCode: 授权码模式支持。
- Token: Access Token 和 Refresh Token 管理。
- Flows: 支持 Authorization Code, Client Credentials, Refresh Token 等标准流程。
5. 接口规范
5.1 请求处理
- 参数解析: 利用
vigo的泛型 Handler 机制,自动解析 Query, Path, Header, JSON Body 参数到结构体。 - 验证: 结构体 Tag (
src,json,default) 定义参数源和默认值。
5.2 响应格式
统一使用 JSON 格式响应,由全局后置中间件 common.JsonResponse 处理:
成功响应:
{
"code": 200,
"data": { ... } // 或 null
}
错误响应:
{
"code": 400, // 或 401, 403, 500 等
"message": "错误描述信息"
}
6. 数据库设计
推荐使用 vigo.Model 作为基类,统一包含以下字段:
ID: UUID (varchar(36))CreatedAt: 创建时间UpdatedAt: 更新时间DeletedAt: 软删除标记
所有模型在 models/init.go 中注册,支持服务启动时自动迁移 (AutoMigrate)。
7. 部署与运维
- 配置: 支持
.env文件和环境变量覆盖。 - 构建:
go build -o vbase cli/main.go - 运行:
./vbase -p 8080
8. 开发规范
- 资源命名: 权限资源标识符必须使用
kebab-case(如oauth-client) 或snake_case,禁止使用冒号。 - 错误处理: 优先使用
vigo.NewError或预定义错误 (如vigo.ErrNotFound),以便统一处理 HTTP 状态码。 - 测试: 编写集成测试脚本 (
test.sh,full_test.sh) 覆盖核心业务流程。
9. 实战场景指南 (Use Cases)
VBase 的 Org (组织) 设计非常灵活,既支持单租户应用,也支持复杂的多租户 B2B 系统。以下是几种典型场景的最佳实践。
场景一:B2C 电商平台 / 简单应用 (Single Tenant)
示例: 网上书店、个人博客、C端工具应用。 特点: 所有用户直接面对平台,不存在“团队”或“公司”的概念。
-
Org 使用策略:
- 忽略 Org: 绝大多数 API 请求不需要携带
X-Org-ID。 - 权限管理: 用户角色(如
admin,user)直接绑定到 Global 域 (org_id="")。 - 数据隔离: 数据通常是全局可见(如商品列表)或基于
UserID隔离(如用户订单)。
- 忽略 Org: 绝大多数 API 请求不需要携带
-
权限模型:
- 管理员: 拥有全局
admin角色,管理所有书籍 (book:create,book:delete)。 - 普通用户: 拥有全局
user角色,可以浏览和购买 (book:read,order:create)。 - 接口调用: 客户端无需处理
OrgID,直接使用 Token 访问。
- 管理员: 拥有全局
场景二:B2B SaaS 系统 (Multi-Tenant)
示例: 项目管理工具 (Jira)、企业协作平台 (Slack)、HR 系统。 特点: 客户以“公司”或“团队”为单位,数据严格隔离。
-
Org 使用策略:
- 强制 Org: 几乎所有业务 API (如创建任务、查看员工) 都必须在 Header 中携带
X-Org-ID。 - 数据隔离: 数据库查询必须带上
Where("org_id = ?", ctxOrgID)。 - 角色复用: 同一个用户 (User) 可以加入多个组织 (Org),在不同组织中拥有不同角色 (在 A 公司是管理员,在 B 公司是普通成员)。
- 强制 Org: 几乎所有业务 API (如创建任务、查看员工) 都必须在 Header 中携带
-
权限模型:
- 用户张三:
- 在 字节跳动 (OrgA): 角色
admin-> 权限project:create,member:add。 - 在 个人工作室 (OrgB): 角色
viewer-> 权限project:read。
- 在 字节跳动 (OrgA): 角色
- 鉴权流程:
AuthMiddleware会自动校验张三是否是目标 Org 的成员,并将对应的角色权限加载到上下文中。
- 用户张三:
场景三:双边市场 / 平台型 SaaS (Hybrid)
示例: 淘宝/亚马逊 (平台 + 商家)、外卖平台。 特点: 既有平台运营方,又有独立商家 (Org),还有 C 端消费者。
-
Org 使用策略:
- 商家端 (Seller): 类似 B2B 模式。商家登录后,操作店铺数据需携带
X-Org-ID(店铺ID)。 - 消费者端 (Buyer): 类似 B2C 模式。消费者浏览商品不需要 Org 上下文,或者处于一个特殊的“公域”上下文中。
- 平台管理 (Platform Admin): 拥有全局超级权限,可以管理所有 Org。
- 商家端 (Seller): 类似 B2B 模式。商家登录后,操作店铺数据需携带
-
权限模型:
- 平台管理员: 全局
super_admin,可封禁任何商家 (org:delete)。 - 商家: 在自己的 Org 内拥有
shop_admin,管理自家商品 (product:create)。 - 消费者: 全局
buyer,可跨 Org 下单 (order:create)。
- 平台管理员: 全局
总结
| 场景 | Org 角色 | 权限绑定 | 请求 Header | 数据隔离方式 |
|---|---|---|---|---|
| B2C (书店) | 不使用 / 仅后台用 | 全局绑定 (org_id="") |
无需 X-Org-ID |
基于 UserID 或公开 |
| B2B (Jira) | 核心隔离单元 | 绑定到特定 Org | 必须 X-Org-ID |
严格基于 OrgID |
| 平台 (淘宝) | 商家店铺 | 商家绑定 Org / 买家全局 | 商家端需要 / 买家端不需要 | 商家数据基于 OrgID |
在 VBase 中,通过 CheckPermission 接口的逻辑(优先检查指定 Org 的角色,若无则检查全局角色),可以完美兼容上述所有模式。