mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-19 19:04:23 +08:00
feat(auth): 添加 SECTL Auth OAuth 登录功能
- 新增 OAuth 登录组件和回调页面 - 集成 Tauri 深度链接插件处理 OAuth 回调 - 添加账户设置页面显示登录信息 - 更新 CI 配置添加 OAuth 环境变量 - 扩展 API 接口支持 OAuth 相关操作 - 添加国际化支持
This commit is contained in:
+922
@@ -0,0 +1,922 @@
|
||||
# SECTL Auth API 参考
|
||||
|
||||
本文档详细说明 SECTL Auth 提供的所有 API 接口。
|
||||
|
||||
## 基础信息
|
||||
|
||||
- **基础 URL**: `https://sectl.top`
|
||||
- **认证方式**: OAuth 2.0 + Bearer Token
|
||||
- **数据格式**: JSON
|
||||
|
||||
## 接口概览
|
||||
|
||||
| 接口 | 方法 | 说明 | 对应页面 |
|
||||
| ----------------------- | ---- | ------------------- | ------------------------ |
|
||||
| `/oauth/authorize` | GET | 获取授权码 | OAuthAuthorizeView.vue |
|
||||
| `/api/oauth/token` | POST | 换取/刷新令牌 | AuthCallbackView.vue |
|
||||
| `/api/oauth/userinfo` | GET | 获取用户信息 | PlatformUsersView.vue |
|
||||
| `/api/oauth/config` | POST | 配置 Token 过期时间 | PlatformSettingsView.vue |
|
||||
| `/api/oauth/revoke` | POST | 撤销令牌 | SecurityView.vue |
|
||||
| `/api/oauth/introspect` | POST | 验证令牌 | - |
|
||||
|
||||
---
|
||||
|
||||
## OAuth 接口
|
||||
|
||||
### 1. 获取授权码
|
||||
|
||||
引导用户跳转到授权页面。
|
||||
|
||||
```http
|
||||
GET /oauth/authorize
|
||||
```
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| ------------- | ------ | ---- | ---------------- |
|
||||
| client_id | string | ✅ | 平台 ID |
|
||||
| redirect_uri | string | ✅ | 回调 URL |
|
||||
| response_type | string | ✅ | 固定值 `code` |
|
||||
| state | string | ❌ | 防 CSRF 状态参数 |
|
||||
|
||||
**示例请求:**
|
||||
|
||||
```
|
||||
https://sectl.top/oauth/authorize?client_id=pf_AHmIhAiptyLFxk8x&redirect_uri=http://localhost:5000/callback&response_type=code
|
||||
```
|
||||
|
||||
**成功响应:**
|
||||
|
||||
- 重定向到 `redirect_uri?code={authorization_code}&state={state}`
|
||||
|
||||
**错误响应:**
|
||||
|
||||
- 重定向到 `redirect_uri?error={error_code}&error_description={description}`
|
||||
|
||||
**错误码:**
|
||||
|
||||
| 错误码 | 说明 |
|
||||
| ------------------------- | ------------------ |
|
||||
| invalid_request | 请求参数缺失或无效 |
|
||||
| unauthorized_client | 客户端未授权 |
|
||||
| access_denied | 用户拒绝授权 |
|
||||
| unsupported_response_type | 不支持的响应类型 |
|
||||
| invalid_scope | 无效的权限范围 |
|
||||
| server_error | 服务器内部错误 |
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue) - 授权页面
|
||||
- [LoginView.vue](../../src/views/LoginView.vue) - 登录页面
|
||||
|
||||
---
|
||||
|
||||
### 2. 获取访问令牌
|
||||
|
||||
使用授权码换取访问令牌。
|
||||
|
||||
```http
|
||||
POST /api/oauth/token
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**请求体:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| ------------- | ------ | ---- | ------------------------------------------------ |
|
||||
| grant_type | string | ✅ | `authorization_code` 或 `refresh_token` |
|
||||
| code | string | 条件 | 授权码(grant_type=authorization_code 时必填) |
|
||||
| refresh_token | string | 条件 | 刷新令牌(grant_type=refresh_token 时必填) |
|
||||
| client_id | string | ✅ | 平台 ID |
|
||||
| client_secret | string | ✅ | 平台密钥 |
|
||||
| redirect_uri | string | 条件 | 回调地址(grant_type=authorization_code 时必填) |
|
||||
|
||||
**授权码模式示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"grant_type": "authorization_code",
|
||||
"code": "NjliNDIyOTYwMDE4znLUNeWM6J8ye0MC",
|
||||
"client_id": "pf_AHmIhAiptyLFxk8x",
|
||||
"client_secret": "sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1",
|
||||
"redirect_uri": "http://localhost:5000/callback"
|
||||
}
|
||||
```
|
||||
|
||||
**刷新令牌模式示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"grant_type": "refresh_token",
|
||||
"refresh_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"client_id": "pf_AHmIhAiptyLFxk8x",
|
||||
"client_secret": "sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1"
|
||||
}
|
||||
```
|
||||
|
||||
**成功响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"refresh_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 3600
|
||||
}
|
||||
```
|
||||
|
||||
**响应字段:**
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| ------------- | ------ | ----------------------- |
|
||||
| access_token | string | 访问令牌(JWT) |
|
||||
| refresh_token | string | 刷新令牌 |
|
||||
| token_type | string | 令牌类型,固定为 Bearer |
|
||||
| expires_in | number | 过期时间(秒) |
|
||||
|
||||
**错误响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "invalid_grant",
|
||||
"error_description": "Authorization code has expired"
|
||||
}
|
||||
```
|
||||
|
||||
**错误码:**
|
||||
|
||||
| 错误码 | HTTP 状态 | 说明 |
|
||||
| ---------------------- | --------- | ------------------------ |
|
||||
| invalid_request | 400 | 请求格式错误 |
|
||||
| invalid_client | 401 | 客户端认证失败 |
|
||||
| invalid_grant | 400 | 授权码无效或过期 |
|
||||
| unauthorized_client | 400 | 客户端无权使用此授权类型 |
|
||||
| unsupported_grant_type | 400 | 不支持的授权类型 |
|
||||
| invalid_scope | 400 | 无效的权限范围 |
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [AuthCallbackView.vue](../../src/views/AuthCallbackView.vue) - 回调处理
|
||||
|
||||
---
|
||||
|
||||
### 3. 获取用户信息
|
||||
|
||||
使用访问令牌获取用户信息。
|
||||
|
||||
```http
|
||||
GET /api/oauth/userinfo
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Authorization: Bearer {access_token}
|
||||
```
|
||||
|
||||
**成功响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"user_id": "69bd422960018cf4d0e5",
|
||||
"email": "user@example.com",
|
||||
"name": "张三",
|
||||
"github_username": "zhangsan",
|
||||
"permission": 1
|
||||
}
|
||||
```
|
||||
|
||||
**响应字段:**
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --------------- | ------ | --------------------- |
|
||||
| user_id | string | 用户唯一标识 |
|
||||
| email | string | 用户邮箱 |
|
||||
| name | string | 用户名称 |
|
||||
| github_username | string | GitHub 用户名(如有) |
|
||||
| permission | number | 用户权限等级 |
|
||||
|
||||
**错误响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "invalid_token",
|
||||
"error_description": "The access token is invalid or has expired"
|
||||
}
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [PlatformUsersView.vue](../../src/views/dashboard/manage/PlatformUsersView.vue) - 平台用户列表
|
||||
|
||||
---
|
||||
|
||||
### 4. 配置 Token 过期时间
|
||||
|
||||
配置平台的 access_token 过期时间(需要管理员权限)。
|
||||
|
||||
```http
|
||||
POST /api/oauth/config
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**请求体:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| ------------ | ------ | ---- | ------------------------------------------- |
|
||||
| platform_id | string | ✅ | 平台 ID |
|
||||
| expires_in | number | ✅ | 过期时间(秒),-1 表示永不过期,最小 60 秒 |
|
||||
| admin_secret | string | ✅ | 管理员密钥 |
|
||||
|
||||
**请求示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"platform_id": "pf_AHmIhAiptyLFxk8x",
|
||||
"expires_in": 86400,
|
||||
"admin_secret": "your-admin-secret"
|
||||
}
|
||||
```
|
||||
|
||||
**成功响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Token expiration time updated",
|
||||
"expires_in": 86400
|
||||
}
|
||||
```
|
||||
|
||||
**错误响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "unauthorized",
|
||||
"error_description": "Invalid admin secret"
|
||||
}
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue) - 平台设置
|
||||
|
||||
---
|
||||
|
||||
### 5. 撤销令牌
|
||||
|
||||
撤销指定的访问令牌或刷新令牌。
|
||||
|
||||
```http
|
||||
POST /api/oauth/revoke
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**请求体:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| --------------- | ------ | ---- | --------------------------------- |
|
||||
| token | string | ✅ | 要撤销的令牌 |
|
||||
| token_type_hint | string | ❌ | `access_token` 或 `refresh_token` |
|
||||
| client_id | string | ✅ | 平台 ID |
|
||||
| client_secret | string | ✅ | 平台密钥 |
|
||||
|
||||
**请求示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"token_type_hint": "access_token",
|
||||
"client_id": "pf_AHmIhAiptyLFxk8x",
|
||||
"client_secret": "sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1"
|
||||
}
|
||||
```
|
||||
|
||||
**成功响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Token revoked successfully"
|
||||
}
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [SecurityView.vue](../../src/views/dashboard/other/SecurityView.vue) - 安全设置
|
||||
- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue) - 登录平台列表
|
||||
|
||||
---
|
||||
|
||||
### 6. 验证令牌
|
||||
|
||||
验证访问令牌的有效性和获取令牌信息。
|
||||
|
||||
```http
|
||||
POST /api/oauth/introspect
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**请求体:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| ------------- | ------ | ---- | ------------ |
|
||||
| token | string | ✅ | 要验证的令牌 |
|
||||
| client_id | string | ✅ | 平台 ID |
|
||||
| client_secret | string | ✅ | 平台密钥 |
|
||||
|
||||
**请求示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"client_id": "pf_AHmIhAiptyLFxk8x",
|
||||
"client_secret": "sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1"
|
||||
}
|
||||
```
|
||||
|
||||
**活跃令牌响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"active": true,
|
||||
"user_id": "69bd422960018cf4d0e5",
|
||||
"client_id": "pf_AHmIhAiptyLFxk8x",
|
||||
"exp": 1704783600,
|
||||
"iat": 1704780000
|
||||
}
|
||||
```
|
||||
|
||||
**非活跃令牌响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"active": false
|
||||
}
|
||||
```
|
||||
|
||||
**响应字段:**
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --------- | ------- | ------------------------ |
|
||||
| active | boolean | 令牌是否有效 |
|
||||
| user_id | string | 用户 ID(仅活跃令牌) |
|
||||
| client_id | string | 平台 ID(仅活跃令牌) |
|
||||
| exp | number | 过期时间戳(仅活跃令牌) |
|
||||
| iat | number | 签发时间戳(仅活跃令牌) |
|
||||
|
||||
---
|
||||
|
||||
## 平台管理 API
|
||||
|
||||
以下 API 用于管理平台信息,需要通过 Appwrite SDK 调用。
|
||||
|
||||
### 获取平台列表
|
||||
|
||||
```javascript
|
||||
// 使用 Appwrite SDK
|
||||
const result = await databases.listDocuments({
|
||||
databaseId: "69bd89d8000304c37368",
|
||||
collectionId: "platforms",
|
||||
queries: [Query.orderDesc("$createdAt"), Query.limit(100)],
|
||||
})
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue)
|
||||
|
||||
### 获取平台详情
|
||||
|
||||
```javascript
|
||||
const platform = await databases.getDocument({
|
||||
databaseId: "69bd89d8000304c37368",
|
||||
collectionId: "platforms",
|
||||
documentId: "platform-document-id",
|
||||
})
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [PlatformDetailView.vue](../../src/views/dashboard/detail/PlatformDetailView.vue)
|
||||
|
||||
### 更新平台信息
|
||||
|
||||
```javascript
|
||||
await databases.updateDocument({
|
||||
databaseId: "69bd89d8000304c37368",
|
||||
collectionId: "platforms",
|
||||
documentId: "platform-document-id",
|
||||
data: {
|
||||
callback_url: "http://new-callback.com",
|
||||
token_expires_in: 7200,
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue)
|
||||
|
||||
### 申请创建平台
|
||||
|
||||
```javascript
|
||||
await databases.createDocument({
|
||||
databaseId: "69bd89d8000304c37368",
|
||||
collectionId: "platform_applications",
|
||||
documentId: ID.unique(),
|
||||
data: {
|
||||
name: "我的应用",
|
||||
description: "应用描述",
|
||||
callback_url: "http://localhost:5000/callback",
|
||||
owner_id: currentUser.$id,
|
||||
status: "pending",
|
||||
created_at: new Date().toISOString(),
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [PlatformApplyView.vue](../../src/views/dashboard/form/PlatformApplyView.vue)
|
||||
|
||||
---
|
||||
|
||||
## 用户管理 API
|
||||
|
||||
### 获取用户授权的平台列表
|
||||
|
||||
```javascript
|
||||
const result = await databases.listDocuments({
|
||||
databaseId: "69bd89d8000304c37368",
|
||||
collectionId: "oauth_tokens",
|
||||
queries: [Query.equal("user_id", currentUser.$id), Query.equal("revoked", false)],
|
||||
})
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue)
|
||||
|
||||
### 获取平台授权用户列表
|
||||
|
||||
```javascript
|
||||
const result = await databases.listDocuments({
|
||||
databaseId: "69bd89d8000304c37368",
|
||||
collectionId: "oauth_tokens",
|
||||
queries: [Query.equal("platform_id", "pf_xxx"), Query.equal("revoked", false)],
|
||||
})
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [PlatformUsersView.vue](../../src/views/dashboard/manage/PlatformUsersView.vue)
|
||||
|
||||
---
|
||||
|
||||
## 云存储 API
|
||||
|
||||
云存储 API 提供文件上传、下载、管理等功能。需要通过 OAuth access_token 进行认证。
|
||||
|
||||
### 接口概览
|
||||
|
||||
| 接口 | 方法 | 说明 | SDK 方法 |
|
||||
| ------------------------------- | ------ | ------------------------ | ------------------------------- |
|
||||
| `/api/cloud/upload` | POST | 上传文件 | `uploadFile()` |
|
||||
| `/api/cloud/files/{file_id}` | GET | 获取文件信息 | `getFile()` |
|
||||
| `/api/cloud/download/{file_id}` | GET | 获取下载链接 | `downloadFile()` |
|
||||
| `/api/cloud/view/{file_id}` | GET | 查看文件内容 | `viewFile()` |
|
||||
| `/api/cloud/preview/{file_id}` | GET | 预览文件(支持图片处理) | `previewFile()` |
|
||||
| `/api/cloud/info` | GET | 获取存储信息 | `getStorageInfo()` |
|
||||
| `/api/cloud/files` | GET | 列出/搜索文件 | `listFiles()` / `searchFiles()` |
|
||||
| `/api/cloud/files/{file_id}` | PUT | 更新文件(重命名) | `updateFile()` |
|
||||
| `/api/cloud/files/{file_id}` | DELETE | 删除文件 | `deleteFile()` |
|
||||
|
||||
---
|
||||
|
||||
### 1. 上传文件
|
||||
|
||||
上传文件到云存储,系统会自动验证文件格式和检查存储容量。
|
||||
|
||||
```http
|
||||
POST /api/cloud/upload
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Authorization: Bearer {access_token}
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| ----------- | ------ | ---- | ------------ |
|
||||
| file | File | ✅ | 要上传的文件 |
|
||||
| platform_id | string | ✅ | 平台 ID |
|
||||
|
||||
**请求示例(JavaScript):**
|
||||
|
||||
```javascript
|
||||
const formData = new FormData()
|
||||
formData.append("file", fileInput.files[0])
|
||||
formData.append("platform_id", "pf_AHmIhAiptyLFxk8x")
|
||||
|
||||
const response = await fetch("https://sectl.top/api/cloud/upload", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: "Bearer eyJhbGciOiJIUzI1NiIs...",
|
||||
},
|
||||
body: formData,
|
||||
})
|
||||
```
|
||||
|
||||
**成功响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"file_id": "cf_xxxxxxxx",
|
||||
"filename": "example.jpg",
|
||||
"size": 1024567,
|
||||
"url": "https://cloud.appwrite.io/v1/storage/buckets/69c869010007b752a9b1/files/xxx/view",
|
||||
"storage": {
|
||||
"used": "50MB",
|
||||
"limit": "100MB",
|
||||
"available": "50MB",
|
||||
"percentage": 50
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**错误响应 - 格式不允许:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "invalid_format",
|
||||
"error_description": "File format 'exe' is not allowed",
|
||||
"allowed_formats": ["jpg", "png", "pdf"]
|
||||
}
|
||||
```
|
||||
|
||||
**错误响应 - 超出容量:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "storage_exceeded",
|
||||
"error_description": "Upload would exceed storage limit",
|
||||
"storage": {
|
||||
"used": "95MB",
|
||||
"limit": "100MB",
|
||||
"available": "5MB",
|
||||
"requested": "10MB"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [CloudServiceView.vue](../../src/views/dashboard/CloudServiceView.vue) - 云服务总览
|
||||
|
||||
---
|
||||
|
||||
### 2. 下载文件
|
||||
|
||||
获取文件的下载链接。
|
||||
|
||||
```http
|
||||
GET /api/cloud/download/{file_id}
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Authorization: Bearer {access_token}
|
||||
```
|
||||
|
||||
**路径参数:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| ------- | ------ | ---- | ------- |
|
||||
| file_id | string | ✅ | 文件 ID |
|
||||
|
||||
**成功响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"file_id": "cf_xxxxxxxx",
|
||||
"filename": "example.jpg",
|
||||
"download_url": "https://cloud.appwrite.io/v1/storage/buckets/69c869010007b752a9b1/files/xxx/download",
|
||||
"expires_at": "2025-01-01T01:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 获取存储信息
|
||||
|
||||
获取用户在该平台的存储使用情况和配置信息。
|
||||
|
||||
```http
|
||||
GET /api/cloud/info?platform_id={platform_id}
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Authorization: Bearer {access_token}
|
||||
```
|
||||
|
||||
**查询参数:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| ----------- | ------ | ---- | ------- |
|
||||
| platform_id | string | ✅ | 平台 ID |
|
||||
|
||||
**成功响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"platform_id": "pf_xxx",
|
||||
"tier": "free",
|
||||
"storage": {
|
||||
"used": 52428800,
|
||||
"used_formatted": "50MB",
|
||||
"limit": 104857600,
|
||||
"limit_formatted": "100MB",
|
||||
"available": 52428800,
|
||||
"available_formatted": "50MB",
|
||||
"percentage": 50
|
||||
},
|
||||
"allowed_formats": ["jpg", "png", "pdf"],
|
||||
"max_file_size": 10485760
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. 列出文件
|
||||
|
||||
获取用户在该平台的文件列表。
|
||||
|
||||
```http
|
||||
GET /api/cloud/files?platform_id={platform_id}&limit=20&offset=0
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Authorization: Bearer {access_token}
|
||||
```
|
||||
|
||||
**查询参数:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| ----------- | ------ | ---- | ----------------- |
|
||||
| platform_id | string | ✅ | 平台 ID |
|
||||
| limit | number | ❌ | 每页数量,默认 20 |
|
||||
| offset | number | ❌ | 偏移量,默认 0 |
|
||||
|
||||
**成功响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"files": [
|
||||
{
|
||||
"file_id": "cf_xxx",
|
||||
"filename": "example.jpg",
|
||||
"size": 1024567,
|
||||
"size_formatted": "1MB",
|
||||
"created_at": "2025-01-01T00:00:00Z"
|
||||
}
|
||||
],
|
||||
"total": 10,
|
||||
"limit": 20,
|
||||
"offset": 0
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. 删除文件
|
||||
|
||||
删除指定的文件。
|
||||
|
||||
```http
|
||||
DELETE /api/cloud/files/{file_id}
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Authorization: Bearer {access_token}
|
||||
```
|
||||
|
||||
**路径参数:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| ------- | ------ | ---- | ------- |
|
||||
| file_id | string | ✅ | 文件 ID |
|
||||
|
||||
**成功响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "File deleted successfully",
|
||||
"storage": {
|
||||
"used": "45MB",
|
||||
"limit": "100MB",
|
||||
"available": "55MB"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 云存储 SDK
|
||||
|
||||
我们提供了 JavaScript SDK 简化云存储 API 的调用。
|
||||
|
||||
### 安装
|
||||
|
||||
```html
|
||||
<script src="https://sectl.top/platform-sdk/cloud-storage.js"></script>
|
||||
```
|
||||
|
||||
或使用 ES6 模块:
|
||||
|
||||
```javascript
|
||||
import CloudStorage from "./cloud-storage.js"
|
||||
```
|
||||
|
||||
### 初始化
|
||||
|
||||
```javascript
|
||||
const cloud = new CloudStorage({
|
||||
baseUrl: "https://sectl.top",
|
||||
platformId: "your_platform_id",
|
||||
accessToken: "your_access_token",
|
||||
})
|
||||
```
|
||||
|
||||
### 使用示例
|
||||
|
||||
```javascript
|
||||
// 上传文件
|
||||
try {
|
||||
const result = await cloud.uploadFile(fileInput.files[0])
|
||||
console.log("文件上传成功:", result.file_id)
|
||||
console.log("存储使用情况:", result.storage.percentage + "%")
|
||||
} catch (error) {
|
||||
if (error.code === "invalid_format") {
|
||||
console.error("不支持的文件格式:", error.data.allowed_formats)
|
||||
} else if (error.code === "storage_exceeded") {
|
||||
console.error("存储空间不足")
|
||||
}
|
||||
}
|
||||
|
||||
// 获取存储信息
|
||||
const info = await cloud.getStorageInfo()
|
||||
console.log("已用空间:", info.storage.used_formatted)
|
||||
console.log("允许格式:", info.allowed_formats)
|
||||
|
||||
// 列出文件
|
||||
const files = await cloud.listFiles({ limit: 10 })
|
||||
files.files.forEach((file) => {
|
||||
console.log(file.filename, file.size_formatted)
|
||||
})
|
||||
|
||||
// 下载文件
|
||||
const download = await cloud.downloadFile("cf_xxx")
|
||||
window.location.href = download.download_url
|
||||
|
||||
// 删除文件
|
||||
await cloud.deleteFile("cf_xxx")
|
||||
```
|
||||
|
||||
**相关文件:**
|
||||
|
||||
- [cloud-storage.js](../../platform-sdk/cloud-storage.js) - SDK 源码
|
||||
|
||||
---
|
||||
|
||||
## 远程退登 API
|
||||
|
||||
### 创建退登事件
|
||||
|
||||
当用户退出登录时,系统会自动创建退登事件。
|
||||
|
||||
```javascript
|
||||
await databases.createDocument({
|
||||
databaseId: "69bd89d8000304c37368",
|
||||
collectionId: "logout_events",
|
||||
documentId: ID.unique(),
|
||||
data: {
|
||||
user_id: currentUser.$id,
|
||||
platform_id: null, // null 表示全局退出
|
||||
global: true,
|
||||
created_at: new Date().toISOString(),
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### 订阅退登事件
|
||||
|
||||
使用 Appwrite Realtime 订阅退登事件:
|
||||
|
||||
```javascript
|
||||
import { Client } from "appwrite"
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint("https://cloud.appwrite.io/v1")
|
||||
.setProject("your-project-id")
|
||||
|
||||
const unsubscribe = client.subscribe(
|
||||
"databases.69bd89d8000304c37368.collections.logout_events.documents",
|
||||
(response) => {
|
||||
const event = response.payload
|
||||
if (event.user_id === currentUserId) {
|
||||
// 执行本地退出
|
||||
localLogout()
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**相关页面:**
|
||||
|
||||
- [SecurityView.vue](../../src/views/dashboard/other/SecurityView.vue)
|
||||
|
||||
---
|
||||
|
||||
## 错误处理
|
||||
|
||||
### HTTP 状态码
|
||||
|
||||
| 状态码 | 说明 |
|
||||
| ------ | ------------------ |
|
||||
| 200 | 请求成功 |
|
||||
| 400 | 请求参数错误 |
|
||||
| 401 | 未授权,认证失败 |
|
||||
| 403 | 禁止访问,权限不足 |
|
||||
| 404 | 资源不存在 |
|
||||
| 500 | 服务器内部错误 |
|
||||
|
||||
### 错误响应格式
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "error_code",
|
||||
"error_description": "详细的错误描述",
|
||||
"error_uri": "https://docs.example.com/error/error_code"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 安全建议
|
||||
|
||||
1. **使用 HTTPS** - 所有 API 通信必须使用 HTTPS
|
||||
2. **保护密钥** - 不要在客户端代码中暴露 client_secret
|
||||
3. **验证回调地址** - 确保 redirect_uri 与注册时一致
|
||||
4. **使用状态参数** - 添加 state 参数防止 CSRF 攻击
|
||||
5. **安全存储令牌** - Token 应安全存储,避免泄露
|
||||
6. **及时撤销** - 用户退出时及时撤销令牌
|
||||
|
||||
---
|
||||
|
||||
## 相关页面
|
||||
|
||||
- [OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue) - OAuth 授权页面
|
||||
- [AuthCallbackView.vue](../../src/views/AuthCallbackView.vue) - 认证回调
|
||||
- [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue) - 平台管理
|
||||
- [PlatformDetailView.vue](../../src/views/dashboard/detail/PlatformDetailView.vue) - 平台详情
|
||||
- [PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue) - 平台设置
|
||||
- [SecurityView.vue](../../src/views/dashboard/other/SecurityView.vue) - 安全设置
|
||||
- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue) - 登录平台列表
|
||||
Reference in New Issue
Block a user