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

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:actionapp: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 处理:

成功响应:

{
  "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. 开发规范

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