|
|
|
|
|
# OAuth 服务器数据库设计
|
|
|
|
|
|
|
|
|
|
|
|
本文档介绍了基于您现有用户管理系统的OAuth 2.0服务器数据库设计。
|
|
|
|
|
|
|
|
|
|
|
|
## 核心表结构
|
|
|
|
|
|
|
|
|
|
|
|
### 1. OAuth 客户端相关
|
|
|
|
|
|
|
|
|
|
|
|
#### `oauth_clients` - OAuth客户端表
|
|
|
|
|
|
存储注册到系统的OAuth客户端应用信息。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| id | varchar(32) | 主键ID |
|
|
|
|
|
|
| client_id | varchar(255) | 客户端ID(唯一) |
|
|
|
|
|
|
| client_secret | varchar(255) | 客户端密钥(加密存储) |
|
|
|
|
|
|
| client_name | varchar(255) | 客户端应用名称 |
|
|
|
|
|
|
| client_uri | varchar(500) | 客户端主页 |
|
|
|
|
|
|
| logo_uri | varchar(500) | 客户端Logo |
|
|
|
|
|
|
| redirect_uris | text | 重定向URI列表(JSON格式) |
|
|
|
|
|
|
| response_types | varchar(255) | 支持的响应类型 |
|
|
|
|
|
|
| grant_types | varchar(255) | 支持的授权类型 |
|
|
|
|
|
|
| scope | text | 授权范围 |
|
|
|
|
|
|
| is_public | boolean | 是否为公开客户端 |
|
|
|
|
|
|
| is_active | boolean | 是否激活 |
|
|
|
|
|
|
| owner_id | varchar(32) | 客户端拥有者ID |
|
|
|
|
|
|
|
|
|
|
|
|
#### `oauth_scopes` - OAuth授权范围表
|
|
|
|
|
|
定义可用的授权范围。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| id | varchar(32) | 主键ID |
|
|
|
|
|
|
| name | varchar(100) | 范围名称(唯一) |
|
|
|
|
|
|
| display_name | varchar(100) | 显示名称 |
|
|
|
|
|
|
| description | text | 范围描述 |
|
|
|
|
|
|
| is_default | boolean | 是否为默认范围 |
|
|
|
|
|
|
| is_system | boolean | 是否为系统范围 |
|
|
|
|
|
|
|
|
|
|
|
|
#### `oauth_client_scopes` - 客户端授权范围关联表
|
|
|
|
|
|
定义客户端可以请求的授权范围。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| client_id | varchar(32) | 客户端ID |
|
|
|
|
|
|
| scope_id | varchar(32) | 范围ID |
|
|
|
|
|
|
|
|
|
|
|
|
### 2. OAuth 授权流程相关
|
|
|
|
|
|
|
|
|
|
|
|
#### `oauth_authorization_codes` - 授权码表
|
|
|
|
|
|
存储授权码流程中的临时授权码。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| id | varchar(32) | 主键ID |
|
|
|
|
|
|
| code | varchar(255) | 授权码(唯一) |
|
|
|
|
|
|
| client_id | varchar(32) | 客户端ID |
|
|
|
|
|
|
| user_id | varchar(32) | 用户ID |
|
|
|
|
|
|
| redirect_uri | varchar(500) | 重定向URI |
|
|
|
|
|
|
| scope | text | 授权范围 |
|
|
|
|
|
|
| code_challenge | varchar(255) | PKCE代码挑战 |
|
|
|
|
|
|
| code_challenge_method | varchar(50) | PKCE挑战方法 |
|
|
|
|
|
|
| expires_at | timestamp | 过期时间 |
|
|
|
|
|
|
| used | boolean | 是否已使用 |
|
|
|
|
|
|
|
|
|
|
|
|
#### `oauth_access_tokens` - 访问令牌表
|
|
|
|
|
|
存储颁发的访问令牌。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| id | varchar(32) | 主键ID |
|
|
|
|
|
|
| token | varchar(500) | 访问令牌(唯一) |
|
|
|
|
|
|
| client_id | varchar(32) | 客户端ID |
|
|
|
|
|
|
| user_id | varchar(32) | 用户ID |
|
|
|
|
|
|
| scope | text | 授权范围 |
|
|
|
|
|
|
| expires_at | timestamp | 过期时间 |
|
|
|
|
|
|
| revoked | boolean | 是否已撤销 |
|
|
|
|
|
|
|
|
|
|
|
|
#### `oauth_refresh_tokens` - 刷新令牌表
|
|
|
|
|
|
存储刷新令牌,用于获取新的访问令牌。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| id | varchar(32) | 主键ID |
|
|
|
|
|
|
| token | varchar(500) | 刷新令牌(唯一) |
|
|
|
|
|
|
| access_token_id | varchar(32) | 关联的访问令牌ID |
|
|
|
|
|
|
| client_id | varchar(32) | 客户端ID |
|
|
|
|
|
|
| user_id | varchar(32) | 用户ID |
|
|
|
|
|
|
| scope | text | 授权范围 |
|
|
|
|
|
|
| expires_at | timestamp | 过期时间 |
|
|
|
|
|
|
| revoked | boolean | 是否已撤销 |
|
|
|
|
|
|
|
|
|
|
|
|
#### `oauth_user_consents` - 用户授权同意表
|
|
|
|
|
|
记录用户对客户端的授权同意。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| id | varchar(32) | 主键ID |
|
|
|
|
|
|
| user_id | varchar(32) | 用户ID |
|
|
|
|
|
|
| client_id | varchar(32) | 客户端ID |
|
|
|
|
|
|
| scope | text | 授权范围 |
|
|
|
|
|
|
| consent_at | timestamp | 同意时间 |
|
|
|
|
|
|
| expires_at | timestamp | 同意过期时间 |
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 第三方OAuth登录相关
|
|
|
|
|
|
|
|
|
|
|
|
#### `oauth_providers` - 第三方OAuth提供商表
|
|
|
|
|
|
配置第三方OAuth提供商(如GitHub, Google等)。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| id | varchar(32) | 主键ID |
|
|
|
|
|
|
| name | varchar(100) | 提供商名称(唯一) |
|
|
|
|
|
|
| display_name | varchar(100) | 显示名称 |
|
|
|
|
|
|
| client_id | varchar(255) | 客户端ID |
|
|
|
|
|
|
| client_secret | varchar(255) | 客户端密钥 |
|
|
|
|
|
|
| auth_url | varchar(500) | 授权URL |
|
|
|
|
|
|
| token_url | varchar(500) | 令牌URL |
|
|
|
|
|
|
| user_info_url | varchar(500) | 用户信息URL |
|
|
|
|
|
|
| scope | text | 默认授权范围 |
|
|
|
|
|
|
| is_active | boolean | 是否激活 |
|
|
|
|
|
|
|
|
|
|
|
|
#### `oauth_accounts` - 用户OAuth账户表
|
|
|
|
|
|
存储用户通过第三方OAuth登录的账户信息。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| id | varchar(32) | 主键ID |
|
|
|
|
|
|
| user_id | varchar(32) | 本系统用户ID |
|
|
|
|
|
|
| provider_id | varchar(32) | 提供商ID |
|
|
|
|
|
|
| provider_user_id | varchar(255) | 提供商用户ID |
|
|
|
|
|
|
| email | varchar(255) | 邮箱 |
|
|
|
|
|
|
| username | varchar(255) | 用户名 |
|
|
|
|
|
|
| nickname | varchar(255) | 昵称 |
|
|
|
|
|
|
| avatar | varchar(500) | 头像URL |
|
|
|
|
|
|
| access_token | text | 访问令牌 |
|
|
|
|
|
|
| refresh_token | text | 刷新令牌 |
|
|
|
|
|
|
| expires_at | timestamp | 令牌过期时间 |
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 用户会话和令牌管理
|
|
|
|
|
|
|
|
|
|
|
|
#### `user_sessions` - 用户会话表
|
|
|
|
|
|
管理用户登录会话。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| id | varchar(32) | 主键ID |
|
|
|
|
|
|
| user_id | varchar(32) | 用户ID |
|
|
|
|
|
|
| session_id | varchar(255) | 会话ID(唯一) |
|
|
|
|
|
|
| ip_address | varchar(45) | IP地址 |
|
|
|
|
|
|
| user_agent | text | 用户代理 |
|
|
|
|
|
|
| expires_at | timestamp | 过期时间 |
|
|
|
|
|
|
| is_active | boolean | 是否激活 |
|
|
|
|
|
|
| last_activity | timestamp | 最后活动时间 |
|
|
|
|
|
|
|
|
|
|
|
|
#### `user_tokens` - 用户令牌表
|
|
|
|
|
|
管理用户的API令牌等。
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
|
| id | varchar(32) | 主键ID |
|
|
|
|
|
|
| user_id | varchar(32) | 用户ID |
|
|
|
|
|
|
| token_type | varchar(50) | 令牌类型 |
|
|
|
|
|
|
| token | varchar(500) | 令牌值(唯一) |
|
|
|
|
|
|
| name | varchar(100) | 令牌名称 |
|
|
|
|
|
|
| description | text | 令牌描述 |
|
|
|
|
|
|
| scope | text | 授权范围 |
|
|
|
|
|
|
| expires_at | timestamp | 过期时间 |
|
|
|
|
|
|
| last_used_at | timestamp | 最后使用时间 |
|
|
|
|
|
|
| is_active | boolean | 是否激活 |
|
|
|
|
|
|
|
|
|
|
|
|
## 关系说明
|
|
|
|
|
|
|
|
|
|
|
|
### 用户与OAuth的关系
|
|
|
|
|
|
- 一个用户可以拥有多个OAuth客户端(`users.id` -> `oauth_clients.owner_id`)
|
|
|
|
|
|
- 一个用户可以授权多个客户端(`users.id` -> `oauth_user_consents.user_id`)
|
|
|
|
|
|
- 一个用户可以关联多个第三方账户(`users.id` -> `oauth_accounts.user_id`)
|
|
|
|
|
|
|
|
|
|
|
|
### OAuth授权流程关系
|
|
|
|
|
|
- 授权码关联客户端和用户(`oauth_authorization_codes.client_id` -> `oauth_clients.id`)
|
|
|
|
|
|
- 访问令牌关联刷新令牌(`oauth_refresh_tokens.access_token_id` -> `oauth_access_tokens.id`)
|
|
|
|
|
|
|
|
|
|
|
|
### 权限控制
|
|
|
|
|
|
- 基于现有的RBAC系统,为OAuth相关操作定义权限
|
|
|
|
|
|
- 管理员可以管理所有OAuth客户端
|
|
|
|
|
|
- 普通用户只能管理自己的OAuth客户端
|
|
|
|
|
|
|
|
|
|
|
|
## 预定义数据
|
|
|
|
|
|
|
|
|
|
|
|
### 默认授权范围
|
|
|
|
|
|
- `profile`: 基本资料访问
|
|
|
|
|
|
- `email`: 邮箱地址访问
|
|
|
|
|
|
- `phone`: 手机号码访问
|
|
|
|
|
|
- `read`: 读取权限
|
|
|
|
|
|
- `write`: 写入权限
|
|
|
|
|
|
- `admin`: 管理员权限
|
|
|
|
|
|
|
|
|
|
|
|
### 预配置的第三方提供商
|
|
|
|
|
|
- GitHub
|
|
|
|
|
|
- Google
|
|
|
|
|
|
- 微信
|
|
|
|
|
|
- 钉钉
|
|
|
|
|
|
|
|
|
|
|
|
### OAuth相关权限
|
|
|
|
|
|
- `oauth.client.create`: 创建OAuth客户端
|
|
|
|
|
|
- `oauth.client.read`: 查看OAuth客户端
|
|
|
|
|
|
- `oauth.client.update`: 更新OAuth客户端
|
|
|
|
|
|
- `oauth.client.delete`: 删除OAuth客户端
|
|
|
|
|
|
- `oauth.token.manage`: 管理OAuth令牌
|
|
|
|
|
|
- `oauth.scope.manage`: 管理OAuth作用域
|
|
|
|
|
|
- `oauth.provider.manage`: 管理OAuth提供商
|
|
|
|
|
|
|
|
|
|
|
|
## 安全考虑
|
|
|
|
|
|
|
|
|
|
|
|
1. **令牌存储**: 所有敏感令牌都应该进行哈希或加密存储
|
|
|
|
|
|
2. **HTTPS强制**: 所有OAuth端点必须使用HTTPS
|
|
|
|
|
|
3. **PKCE支持**: 支持PKCE以增强安全性
|
|
|
|
|
|
4. **令牌过期**: 设置合理的令牌过期时间
|
|
|
|
|
|
5. **审计日志**: 记录所有OAuth相关操作
|
|
|
|
|
|
|
|
|
|
|
|
## 使用示例
|
|
|
|
|
|
|
|
|
|
|
|
### 初始化OAuth数据
|
|
|
|
|
|
```go
|
|
|
|
|
|
import "vyes_cli/oauth"
|
|
|
|
|
|
|
|
|
|
|
|
// 在数据库迁移后调用
|
|
|
|
|
|
err := oauth.InitializeOAuthData(db)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
log.Fatal("Failed to initialize OAuth data:", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 创建测试客户端
|
|
|
|
|
|
```go
|
|
|
|
|
|
client, err := oauth.CreateDefaultOAuthClient(db, adminUserID)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
log.Fatal("Failed to create default OAuth client:", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
这个设计基于OAuth 2.0 RFC标准,同时考虑了您现有的用户管理系统架构,可以无缝集成到您的项目中。
|