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/doc/architecture.md

540 lines
26 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 是一个类似 **Supabase****Backend-as-a-Service (BaaS)** 平台为个人开发者2C和团队/企业2B提供后端资源托管和权限管理服务。采用 Go 语言开发,基于 Vigo 框架构建。
### 1.1 产品定位
| 用户类型 | 使用场景 | 功能需求 |
|----------|----------|----------|
| **个人开发者 (2C)** | 创建个人项目,管理应用后端资源 | 项目管理、资源隔离、API 访问 |
| **团队/初创 (2B)** | 团队协作开发,共享项目资源 | 成员管理、角色权限、组织隔离 |
| **企业客户 (2B)** | 多项目/多团队管理,合规要求 | 组织架构、细粒度权限、审计日志 |
### 1.2 核心特性
- **项目-资源管理**: 用户可以创建多个项目,每个项目包含独立的后端资源
- **灵活的成员协作**: 支持邀请其他用户加入项目,分配不同角色权限
- **多层级权限控制**: 平台级 → 项目级 → 资源级的三级权限体系
- **RBAC + ABAC 权限模型**: 角色与策略结合的细粒度权限控制
- **OAuth2.0/OIDC 服务端**: 支持作为身份提供商,为应用提供认证服务
- **第三方登录集成**: Google、GitHub、微信等快速登录
- **JWT 认证**: 无状态的 Token 认证机制
### 1.3 技术栈
| 层级 | 技术 |
|------|------|
| 框架 | Vigo (Go Web Framework) |
| ORM | GORM |
| 数据库 | MySQL / PostgreSQL / SQLite |
| 缓存 | Redis |
| 认证 | JWT (github.com/golang-jwt/jwt) |
| 密码哈希 | bcrypt |
### 1.4 概念说明
**项目 (Project/Org)**: 资源管理的基本单元
- 个人开发者创建的项目 = 个人项目
- 团队创建的项目 = 团队项目
- 企业可以创建多个项目,也可以使用组织层级管理
**用户 (User)**: 平台注册用户
- 可以创建多个项目
- 可以被邀请加入其他项目
- 在不同项目中可以有不同的角色
**资源 (Resource)**: 项目内的后端资源
- 数据库、存储、函数、API 等
- 属于特定项目
- 通过项目权限控制访问
**角色 (Role)**: 项目内的权限集合
- 所有者 (Owner): 项目全部权限
- 管理员 (Admin): 管理项目和成员
- 开发者 (Developer): 读写资源
- 访客 (Viewer): 只读访问
---
## 2. 系统架构
### 2.1 整体架构图
```
┌─────────────────────────────────────────────────────────────┐
│ Client Layer │
│ (Web App / Mobile App / Third-party Services) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ API Gateway │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Auth Filter │ │ Rate Limiter │ │ Org Context │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Application Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Auth │ │ User │ │ Org │ │ OAuth │ │
│ │ Handler │ │ Handler │ │ Handler │ │ Handler │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Role │ │ Policy │ │Permission│ │
│ │ Handler │ │ Handler │ │ Service │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Service Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Permission │ │ JWT │ │ Crypto │ │
│ │ Checker │ │ Service │ │ Service │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Data Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ User │ │ Org │ │ OAuth │ ... │
│ │ Model │ │ Model │ │ Model │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MySQL/PostgreSQL │ Redis │ Repository │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
---
## 3. 目录结构
```
vbase/
├── cmd/
│ └── server/ # 应用入口
│ └── main.go
├── internal/
│ ├── api/ # API 层
│ │ ├── auth/ # 认证相关
│ │ │ ├── handler.go # 登录/注册/刷新
│ │ │ └── thirdparty.go # 第三方登录
│ │ ├── user/ # 用户管理
│ │ ├── org/ # 组织管理
│ │ ├── oauth/ # OAuth2.0 服务端
│ │ │ ├── client.go # 客户端管理
│ │ │ ├── oauth.go # 授权流程
│ │ │ └── oidc.go # OIDC 支持
│ │ └── middleware/ # 中间件
│ │ ├── auth.go # JWT 认证
│ │ ├── org.go # 组织上下文
│ │ └── ratelimit.go # 限流
│ ├── service/ # 业务逻辑层
│ │ └── permission.go # 权限检查服务
│ ├── model/ # 数据模型层
│ │ ├── base.go # 基础模型
│ │ ├── user.go # 用户/身份/会话
│ │ ├── org.go # 组织/成员
│ │ ├── policy.go # 策略/角色
│ │ ├── oauth.go # OAuth 相关
│ │ └── migrate.go # 数据库迁移
│ ├── cache/ # 缓存层
│ │ └── redis.go # Redis 封装
│ ├── pkg/ # 工具包
│ │ ├── jwt/ # JWT 工具
│ │ └── crypto/ # 加密工具
│ └── config/ # 配置管理
│ └── config.go
├── doc/ # 文档
└── ui/ # 前端 (忽略)
```
---
## 4. 核心模块设计
### 4.1 认证模块
#### JWT Token 结构
```go
// Claims JWT 声明
type Claims struct {
jwt.RegisteredClaims
UserID string `json:"user_id"`
Username string `json:"username"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Email string `json:"email"`
Orgs []OrgClaim `json:"orgs"` // 用户所属组织
Type string `json:"type"` // access/refresh
}
```
#### 认证流程
1. **登录**: 验证用户名密码 → 生成 Token 对 → 保存会话
2. **访问**: 验证 Token → 解析用户上下文 → 组织上下文
3. **刷新**: 验证 Refresh Token → 生成新 Token 对 → 失效旧 Token
4. **登出**: Token 加入黑名单 → 标记会话失效
### 4.2 权限模块
#### 权限层级
VBase 采用三级权限体系:
```
┌─────────────────────────────────────────────────────────────┐
│ 1. 平台级权限 (Platform) │
│ - 用户管理自己的账号 │
│ - 创建项目 │
│ - 管理第三方登录绑定 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. 项目级权限 (Project) │
│ - 项目设置管理 │
│ - 成员邀请和管理 │
│ - 资源创建和管理 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. 资源级权限 (Resource) │
│ - 数据库读写 │
│ - 存储操作 │
│ - 函数调用 │
└─────────────────────────────────────────────────────────────┘
```
#### 权限模型: RBAC + ABAC
**策略模型:**
```go
type Policy struct {
Resource string // 资源: user/org/resource/*
Action string // 操作: create/read/update/delete/*
Effect string // 效果: allow/deny
Condition string // 条件: "owner", "org_member", 或复杂表达式
Scope string // 作用域: platform/org/resource
}
```
**权限检查流程:**
```
┌─────────────┐
│ 请求进入 │
└──────┬──────┘
┌─────────────┐ 命中 ┌─────────────┐
│ 检查缓存 │──────────→│ 返回结果 │
└──────┬──────┘ └─────────────┘
│ 未命中
┌─────────────┐
│ 检查组织所有者│──────────→│ 允许(缓存) │
└──────┬──────┘ └─────────────┘
│ 不是所有者
┌─────────────┐
│ 获取用户角色 │
└──────┬──────┘
┌─────────────┐
│ 获取角色策略 │
└──────┬──────┘
┌─────────────┐ Deny ┌─────────────┐
│ 检查Deny策略 │───────────→│ 拒绝(缓存) │
└──────┬──────┘ └─────────────┘
│ 无Deny
┌─────────────┐ Allow ┌─────────────┐
│ 检查Allow策略│───────────→│ 允许(缓存) │
└──────┬──────┘ └─────────────┘
│ 无Allow
┌─────────────┐
│ 默认拒绝 │───────────→│ 拒绝(缓存) │
└─────────────┘ └─────────────┘
```
#### 缓存策略
- **缓存键**: `perm:{user_id}:{org_id}:{resource}:{action}`
- **TTL**: 1 分钟
- **缓存失效**: 角色/策略变更时清除相关缓存
### 4.3 项目/组织模块
VBase 中的 "Org" 概念灵活适配不同场景:
#### 场景1: 个人项目 (2C)
```
个人开发者
└── 我的项目A (Org: owner=个人)
└── 我的项目B (Org: owner=个人)
```
- 每个项目是一个独立的 Org
- 资源完全隔离
- 可以邀请其他用户协作
#### 场景2: 团队协作 (2B)
```
创业公司团队
├── Web应用项目 (Org)
│ ├── 所有者: CEO
│ ├── 管理员: CTO
│ └── 开发者: 员工A, 员工B
└── 移动应用项目 (Org)
├── 所有者: CEO
└── ...
```
#### 场景3: 企业多层级 (2B Enterprise)
```
企业层级 (可选功能)
总公司 (level=0)
├── 技术中台 (level=1, Org)
├── 业务线A (level=1)
│ ├── 项目1 (level=2, Org)
│ └── 项目2 (level=2, Org)
└── 业务线B (level=1)
└── 项目3 (level=2, Org)
```
#### 数据隔离
- **项目隔离**: 每个 Org 是独立的资源边界
- **用户-项目关联**: 通过 `OrgMember` 表维护多对多关系
- **资源归属**: 所有资源通过 `org_id` 归属到具体项目
- **跨项目访问**: 需要显式授权,默认隔离
### 4.4 OAuth2.0 服务端
#### 支持的授权流程
| 流程 | 说明 | 适用场景 |
|------|------|----------|
| Authorization Code | 授权码模式 | 服务端应用,最安全 |
| Implicit | 简化模式 | SPA/移动端(不推荐) |
| Client Credentials | 客户端凭证 | 服务间调用 |
| Refresh Token | 刷新令牌 | 延长会话 |
#### 安全特性
- **PKCE**: 防止授权码拦截攻击
- **State**: CSRF 防护
- **Redirect URI 白名单**: 严格匹配
- **Token 过期**: Access Token 1小时Refresh Token 30天
---
## 5. 数据模型
### 5.1 实体关系图 (ER Diagram)
```
┌─────────────────────────────────────────────────────────────────┐
│ 平台层 (Platform) │
├─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ User │ │ Identity │ │ Session │ │
│ (平台用户) │ │ (第三方绑定)│ │ (登录会话) │ │
├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ id (PK) │◄──────┤ user_id │ │ id (PK) │ │
│ username │ │ provider │ │ user_id │ │
│ password │ │ provider_uid│ │ token_id │ │
│ email │ │ access_token│ │ type │ │
│ status │ └─────────────┘ │ expires_at │ │
└──────┬──────┘ └─────────────┘ │
│ │
│ 多对多关系(用户-项目) │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ OrgMember │ │ Org │ │
│ │ (项目成员) │ │ (项目) │ │
│ ├─────────────┤ ├─────────────┤ │
└────────►│ user_id │◄──────┤ id (PK) │ │
│ org_id │──────►│ name │ │
│ role_ids │ │ code │ │
│ status │ │ owner_id │ │
└─────────────┘ │ parent_id* │ │
│ path* │ │
└─────────────┘ │
│ │
│ 1:N │
▼ │
┌─────────────┐ │
│ Resource │ │
│ (项目资源) │ │
│ (db/storage)│ │
└─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 权限层 (Permission) │
├─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ Role │ │ RolePolicy │ │ Policy │ │
│ (项目角色) │ │ (角色策略) │ │ (策略) │ │
├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ id (PK) │◄──────┤ role_id │ │ id (PK) │ │
│ org_id │ │ policy_id │──────►│ code │ │
│ name │ └─────────────┘ │ resource │ │
│ policy_ids │ │ action │ │
│ scope │ │ effect │ │
└─────────────┘ │ condition │ │
│ scope │ │
└─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ OAuth层 (Identity) │
├─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│OAuthClient │ │OAuthAuthz │ │ OAuthToken │ │
│ (OAuth应用) │ │ (授权码) │ │ (访问令牌) │ │
├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ id (PK) │◄──────┤ client_id │ │ id (PK) │ │
│ client_id │ │ user_id │◄──────┤ client_id │ │
│ client_secret│ │ code │ │ user_id │ │
│ redirect_uris│ │ expires_at │ │ access_token│ │
│ owner_id │ └─────────────┘ │ refresh_token│ │
│ org_id │ │ org_id │ │
└─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
### 5.2 关键模型说明
**User (用户)**
- 平台级唯一用户账号
- 可同时参与多个项目
- 支持第三方账号绑定
**Org (项目/组织)**
- 资源管理的基本单元
- 对2C场景: 一个项目 = 一个 Org
- 对2B场景: 可以是项目或企业部门
- 支持层级结构(可选)
**OrgMember (项目成员)**
- 维护用户与项目的关联
- 记录角色分配
- 支持多种成员状态(待审核、正常、禁用)
**Role (角色)**
- 项目内定义的权限集合
- 系统预置角色: owner, admin, developer, viewer
- 支持自定义角色
---
## 6. 接口设计原则
### 6.1 RESTful API
- 使用 HTTP 方法表示操作: GET/POST/PATCH/DELETE
- 使用复数名词表示资源: /users, /orgs
- 使用路径参数表示 ID: /users/{user_id}
### 6.2 请求/响应规范
**成功响应:**
```json
{
"code": 200,
"message": "success",
"data": { ... }
}
```
**错误响应:**
```json
{
"code": 400,
"message": "error description",
"data": null
}
```
### 6.3 分页规范
```json
{
"items": [...],
"total": 100,
"page": 1,
"page_size": 10,
"total_pages": 10
}
```
---
## 7. 安全设计
### 7.1 认证安全
- **密码策略**: bcrypt 哈希,成本因子 12
- **JWT 安全**: HS256 算法,密钥最小 32 字节
- **Token 过期**: 短时效 Access Token + 长时效 Refresh Token
- **Token 撤销**: 黑名单机制
### 7.2 接口安全
- **限流**: 基于 IP 和用户 ID 的滑动窗口限流
- **CSRF 防护**: State 参数、SameSite Cookie
- **SQL 注入**: GORM 参数化查询
- **XSS 防护**: 响应头设置 Content-Type
### 7.3 OAuth 安全
- **PKCE**: 所有移动端/SPA 必须使用
- **Redirect URI 严格匹配**: 包括路径和查询参数
- **Scope 限制**: 每个客户端有允许的范围白名单
---
## 8. 扩展性设计
### 8.1 水平扩展
- **无状态服务**: 不依赖本地存储,可水平扩展
- **共享缓存**: Redis 集群支持
- **数据库读写分离**: GORM 支持读写分离配置
### 8.2 插件化
- **中间件链**: 可插拔的中间件设计
- **策略引擎**: 支持自定义条件表达式
- **第三方登录**: 易于添加新的 OAuth 提供商
---
## 9. 监控与日志
### 9.1 日志规范
- 请求日志: 方法、路径、耗时、状态码
- 错误日志: 堆栈追踪、上下文信息
- 审计日志: 敏感操作记录
### 9.2 指标监控
- QPS、响应时间、错误率
- 缓存命中率
- 数据库连接池状态