|
|
# VBase 后端架构设计文档
|
|
|
|
|
|
## 1. 概览
|
|
|
|
|
|
VBase 是一个基于 Golang 的高性能后端基础框架,旨在提供一套标准化的用户管理、组织架构(多租户)、权限控制(RBAC)和 OAuth2 认证服务。项目采用分层架构设计,基于 `vigo` 框架构建,强调代码的可维护性、扩展性和安全性。
|
|
|
|
|
|
## 2. 技术栈
|
|
|
|
|
|
- **语言**: Golang 1.22+
|
|
|
- **Web 框架**: [vigo](https://github.com/veypi/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` 实例,支持多种验证方式:
|
|
|
|
|
|
1. **基础权限**: `Perm("resource:action")` - 检查用户是否拥有指定权限。
|
|
|
2. **资源所有者**: `PermWithOwner("resource:action", "owner_id_key")` - 如果用户是资源所有者则放行,否则检查权限。
|
|
|
3. **特定资源**: `PermOnResource("resource:action", "resource_id_key")` - 检查用户对特定资源实例的权限。
|
|
|
4. **组合权限**: `PermAny`, `PermAll` - 支持“任一”或“所有”权限的逻辑组合。
|
|
|
5. **通配符支持**: 支持 `*` 通配符,如 `app:resource:*` 匹配该资源下的所有操作。
|
|
|
|
|
|
#### 4.1.3 中间件流程
|
|
|
|
|
|
1. **AuthMiddleware**: 解析 JWT Token,提取 UserID 和 OrgID,注入到请求上下文 (`vigo.X`)。
|
|
|
2. **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` 处理:
|
|
|
|
|
|
**成功响应**:
|
|
|
```json
|
|
|
{
|
|
|
"code": 200,
|
|
|
"data": { ... } // 或 null
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**错误响应**:
|
|
|
```json
|
|
|
{
|
|
|
"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. 开发规范
|
|
|
|
|
|
1. **资源命名**: 权限资源标识符必须使用 `kebab-case` (如 `oauth-client`) 或 `snake_case`,**禁止使用冒号**。
|
|
|
2. **错误处理**: 优先使用 `vigo.NewError` 或预定义错误 (如 `vigo.ErrNotFound`),以便统一处理 HTTP 状态码。
|
|
|
3. **测试**: 编写集成测试脚本 (`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` 隔离(如用户订单)。
|
|
|
|
|
|
- **权限模型**:
|
|
|
- **管理员**: 拥有全局 `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 公司是普通成员)。
|
|
|
|
|
|
- **权限模型**:
|
|
|
- **用户张三**:
|
|
|
- 在 **字节跳动 (OrgA)**: 角色 `admin` -> 权限 `project:create`, `member:add`。
|
|
|
- 在 **个人工作室 (OrgB)**: 角色 `viewer` -> 权限 `project:read`。
|
|
|
- **鉴权流程**: `AuthMiddleware` 会自动校验张三是否是目标 Org 的成员,并将对应的角色权限加载到上下文中。
|
|
|
|
|
|
### 场景三:双边市场 / 平台型 SaaS (Hybrid)
|
|
|
|
|
|
**示例**: 淘宝/亚马逊 (平台 + 商家)、外卖平台。
|
|
|
**特点**: 既有平台运营方,又有独立商家 (Org),还有 C 端消费者。
|
|
|
|
|
|
- **Org 使用策略**:
|
|
|
- **商家端 (Seller)**: 类似 B2B 模式。商家登录后,操作店铺数据需携带 `X-Org-ID` (店铺ID)。
|
|
|
- **消费者端 (Buyer)**: 类似 B2C 模式。消费者浏览商品不需要 Org 上下文,或者处于一个特殊的“公域”上下文中。
|
|
|
- **平台管理 (Platform Admin)**: 拥有全局超级权限,可以管理所有 Org。
|
|
|
|
|
|
- **权限模型**:
|
|
|
- **平台管理员**: 全局 `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 的角色,若无则检查全局角色),可以完美兼容上述所有模式。
|