You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/docs/design.md

205 lines
9.4 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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 的角色,若无则检查全局角色),可以完美兼容上述所有模式。