feat: 实现 Token 认证系统
- 后端:Lua 实现 Token 验证、权限控制、限流、审计日志 - API:创建/列出/查看/更新/删除 Token - Web UI:Token 管理界面(列表、创建、详情、编辑、删除弹框) - 向后兼容:保留 X-Password 超级管理员认证 - 安全增强:失败次数限制、过期检测、双因素验证(敏感操作) 需求文档:TOKEN_AUTH_REQUIREMENT.md
This commit is contained in:
1 parent
1567a3dea3
commit
2cf807b59c
4 files changed
+1870
-15
No files matched your search
@@ -0,0 +1,700 @@
|
||||
# Token 认证系统需求文档
|
||||
|
||||
## 1. 项目背景
|
||||
|
||||
当前数据同步服务使用单一密码 `admin123123123` 进行认证,存在以下问题:
|
||||
- 无法区分不同客户端的访问
|
||||
- 无法追踪访问来源和使用情况
|
||||
- 泄露后需要全局修改所有客户端配置
|
||||
- 无法对不同客户端进行细粒度的权限控制
|
||||
|
||||
## 2. 核心目标
|
||||
|
||||
在保持向后兼容的前提下,增加 Token 认证机制,实现:
|
||||
- 多 Token 管理(不同客户端使用不同 Token)
|
||||
- 访问审计(记录每个 Token 的使用情况)
|
||||
- 权限控制(只读/读写)
|
||||
- 安全增强(失败次数限制、限流、双因素验证)
|
||||
|
||||
## 3. 功能需求
|
||||
|
||||
### 3.1 Token 设计
|
||||
|
||||
#### Token 生成规则
|
||||
- **格式**:`dss_` + 32位随机字符串(十六进制)
|
||||
- **示例**:`dss_a1b2c3d4e5f6789012345678901234ab`
|
||||
- **唯一性**:每个 Token 全局唯一
|
||||
|
||||
#### Token 属性
|
||||
```json
|
||||
{
|
||||
"token": "dss_a1b2c3d4e5f6789012345678901234ab",
|
||||
"name": "生产服务器A",
|
||||
"permission": "readonly",
|
||||
"status": "active",
|
||||
"created_at": "2026-09-13 10:30:00",
|
||||
"expires_at": null,
|
||||
"stats": {
|
||||
"total_requests": 1523,
|
||||
"last_used_at": "2026-09-13 15:20:10",
|
||||
"last_ip": "192.168.1.100",
|
||||
"failed_attempts": 0
|
||||
},
|
||||
"access_log": []
|
||||
}
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `token`: Token 字符串
|
||||
- `name`: 用户自定义名称(必填,用于识别客户端)
|
||||
- `permission`: 权限级别
|
||||
- `readonly`: 只读(只能 GET)
|
||||
- `readwrite`: 读写(可 GET/POST/DELETE)
|
||||
- `status`: Token 状态
|
||||
- `active`: 启用
|
||||
- `disabled`: 禁用
|
||||
- `expired`: 已过期
|
||||
- `created_at`: 创建时间
|
||||
- `expires_at`: 过期时间(null 表示永久有效)
|
||||
- `stats.total_requests`: 累计请求次数
|
||||
- `stats.last_used_at`: 最后使用时间
|
||||
- `stats.last_ip`: 最后使用的 IP 地址
|
||||
- `stats.failed_attempts`: 连续失败次数(达到 5 次自动禁用)
|
||||
- `access_log`: 访问日志数组(保留最近 20 条)
|
||||
|
||||
#### 访问日志格式
|
||||
```json
|
||||
{
|
||||
"timestamp": "2026-09-13 15:20:10",
|
||||
"ip": "192.168.1.100",
|
||||
"method": "GET",
|
||||
"path": "/api/data/weibo:ykaayk",
|
||||
"status": 200,
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 API 设计
|
||||
|
||||
#### 认证方式
|
||||
|
||||
**新方式(推荐)**:
|
||||
```http
|
||||
GET /api/data/weibo:ykaayk
|
||||
X-Token: dss_a1b2c3d4e5f6789012345678901234ab
|
||||
```
|
||||
|
||||
**旧方式(兼容保留)**:
|
||||
```http
|
||||
GET /api/data/weibo:ykaayk
|
||||
X-Password: admin123123123
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- `X-Password` 作为超级管理员密码,拥有所有权限,不计入审计日志
|
||||
- `X-Token` 为普通 Token,受权限和限流控制,记录审计日志
|
||||
- 两种方式可以并存,优先检查 `X-Token`
|
||||
|
||||
#### Token 管理 API
|
||||
|
||||
##### 1. 创建 Token
|
||||
```http
|
||||
POST /api/tokens
|
||||
X-Password: admin123123123
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "生产服务器A",
|
||||
"permission": "readonly",
|
||||
"expires_in": null
|
||||
}
|
||||
```
|
||||
|
||||
**参数说明**:
|
||||
- `name`: Token 名称(必填)
|
||||
- `permission`: 权限(必填,`readonly` 或 `readwrite`)
|
||||
- `expires_in`: 过期时间(秒,可选,null 表示永久)
|
||||
- 2592000 = 30天
|
||||
- 7776000 = 90天
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"token": "dss_a1b2c3d4e5f6789012345678901234ab",
|
||||
"name": "生产服务器A",
|
||||
"permission": "readonly",
|
||||
"created_at": "2026-09-13 10:30:00",
|
||||
"expires_at": null
|
||||
}
|
||||
```
|
||||
|
||||
##### 2. 列出所有 Token
|
||||
```http
|
||||
GET /api/tokens
|
||||
X-Password: admin123123123
|
||||
```
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"tokens": [
|
||||
{
|
||||
"token": "dss_a1b2c3...(前12位)",
|
||||
"token_full": "dss_a1b2c3d4e5f6789012345678901234ab",
|
||||
"name": "生产服务器A",
|
||||
"permission": "readonly",
|
||||
"status": "active",
|
||||
"created_at": "2026-09-13 10:30:00",
|
||||
"expires_at": null,
|
||||
"stats": {
|
||||
"total_requests": 1523,
|
||||
"last_used_at": "2026-09-13 15:20:10",
|
||||
"last_ip": "192.168.1.100",
|
||||
"failed_attempts": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
##### 3. 获取 Token 详情
|
||||
```http
|
||||
GET /api/tokens/:token
|
||||
X-Password: admin123123123
|
||||
```
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"token": "dss_a1b2c3d4e5f6789012345678901234ab",
|
||||
"name": "生产服务器A",
|
||||
"permission": "readonly",
|
||||
"status": "active",
|
||||
"created_at": "2026-09-13 10:30:00",
|
||||
"expires_at": null,
|
||||
"stats": {
|
||||
"total_requests": 1523,
|
||||
"last_used_at": "2026-09-13 15:20:10",
|
||||
"last_ip": "192.168.1.100",
|
||||
"failed_attempts": 0
|
||||
},
|
||||
"access_log": [
|
||||
{
|
||||
"timestamp": "2026-09-13 15:20:10",
|
||||
"ip": "192.168.1.100",
|
||||
"method": "GET",
|
||||
"path": "/api/data/weibo:ykaayk",
|
||||
"status": 200
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
##### 4. 更新 Token 状态
|
||||
```http
|
||||
PATCH /api/tokens/:token
|
||||
X-Password: admin123123123
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"status": "disabled"
|
||||
}
|
||||
```
|
||||
|
||||
**可更新字段**:
|
||||
- `status`: `active` 或 `disabled`
|
||||
- `name`: 重命名
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"token": "dss_a1b2c3d4e5f6789012345678901234ab",
|
||||
"status": "disabled"
|
||||
}
|
||||
```
|
||||
|
||||
##### 5. 删除 Token(需要二次确认)
|
||||
```http
|
||||
DELETE /api/tokens/:token
|
||||
X-Password: admin123123123
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"confirm_password": "admin123123123"
|
||||
}
|
||||
```
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Token deleted",
|
||||
"token": "dss_a1b2c3d4e5f6789012345678901234ab"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 权限控制
|
||||
|
||||
#### 只读权限(readonly)
|
||||
- ✅ `GET /api/data/:tag`
|
||||
- ✅ `GET /api/data`
|
||||
- ❌ `POST /api/data`
|
||||
- ❌ `DELETE /api/data/:tag`
|
||||
|
||||
#### 读写权限(readwrite)
|
||||
- ✅ 所有操作
|
||||
|
||||
#### 权限验证失败响应
|
||||
```json
|
||||
{
|
||||
"error": "Permission denied",
|
||||
"message": "This token has readonly permission",
|
||||
"required": "readwrite"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 安全机制
|
||||
|
||||
#### 1. 限流(Rate Limiting)
|
||||
- **规则**:每个 Token 每分钟最多 60 次请求
|
||||
- **超出后响应**:
|
||||
```json
|
||||
{
|
||||
"error": "Rate limit exceeded",
|
||||
"message": "Maximum 60 requests per minute",
|
||||
"retry_after": 30
|
||||
}
|
||||
```
|
||||
- **状态码**:429
|
||||
|
||||
#### 2. 失败次数限制
|
||||
- **规则**:连续失败 5 次自动禁用 Token
|
||||
- **失败场景**:
|
||||
- Token 不存在
|
||||
- Token 已过期
|
||||
- Token 已禁用
|
||||
- **自动禁用后响应**:
|
||||
```json
|
||||
{
|
||||
"error": "Token disabled",
|
||||
"message": "Token has been disabled due to too many failed attempts",
|
||||
"failed_attempts": 5
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 过期检测
|
||||
- 每次请求时检查 `expires_at`
|
||||
- 过期 Token 自动标记为 `expired` 状态
|
||||
- 过期响应:
|
||||
```json
|
||||
{
|
||||
"error": "Token expired",
|
||||
"expires_at": "2026-09-10 10:30:00"
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. 双因素验证(敏感操作)
|
||||
敏感操作需要同时提供 Token 和主密码:
|
||||
- 删除 Token
|
||||
- 修改 Token 权限(从 readonly 改为 readwrite)
|
||||
|
||||
### 3.5 数据存储
|
||||
|
||||
#### 文件结构
|
||||
```
|
||||
/data/
|
||||
tokens.json # Token 索引和基本信息
|
||||
tokens/
|
||||
dss_a1b2c3...json # 单个 Token 的完整数据
|
||||
```
|
||||
|
||||
#### tokens.json 格式
|
||||
```json
|
||||
{
|
||||
"tokens": {
|
||||
"dss_a1b2c3d4e5f6789012345678901234ab": {
|
||||
"name": "生产服务器A",
|
||||
"permission": "readonly",
|
||||
"status": "active",
|
||||
"created_at": "2026-09-13 10:30:00",
|
||||
"expires_at": null,
|
||||
"file": "tokens/dss_a1b2c3d4e5f6789012345678901234ab.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 单个 Token 文件格式
|
||||
```json
|
||||
{
|
||||
"token": "dss_a1b2c3d4e5f6789012345678901234ab",
|
||||
"name": "生产服务器A",
|
||||
"permission": "readonly",
|
||||
"status": "active",
|
||||
"created_at": "2026-09-13 10:30:00",
|
||||
"expires_at": null,
|
||||
"stats": {
|
||||
"total_requests": 1523,
|
||||
"last_used_at": "2026-09-13 15:20:10",
|
||||
"last_ip": "192.168.1.100",
|
||||
"failed_attempts": 0
|
||||
},
|
||||
"access_log": [
|
||||
{
|
||||
"timestamp": "2026-09-13 15:20:10",
|
||||
"ip": "192.168.1.100",
|
||||
"method": "GET",
|
||||
"path": "/api/data/weibo:ykaayk",
|
||||
"status": 200
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 4. Web 界面需求
|
||||
|
||||
### 4.1 Token 管理页面
|
||||
|
||||
#### 入口
|
||||
在现有 Web 管理界面(`http://124.220.209.75:5001/`)顶部导航栏添加:
|
||||
```
|
||||
[数据管理] [Token 管理]
|
||||
```
|
||||
|
||||
#### Token 列表页
|
||||
|
||||
**布局**:
|
||||
```
|
||||
+----------------------------------------------------------+
|
||||
| Token 管理 [+ 创建 Token] |
|
||||
+----------------------------------------------------------+
|
||||
| 搜索: [__________] 状态: [全部 ▼] 权限: [全部 ▼] |
|
||||
+----------------------------------------------------------+
|
||||
| 名称 | Token (前12位) | 权限 | 状态 | 最后使用 | 操作 |
|
||||
|----------------|---------------|-------|------|-----------|------------|
|
||||
| 生产服务器A | dss_a1b2c3... | 只读 | 启用 | 5分钟前 | [详情][禁用][删除] |
|
||||
| 测试脚本 | dss_xyz789... | 读写 | 禁用 | 2天前 | [详情][启用][删除] |
|
||||
+----------------------------------------------------------+
|
||||
```
|
||||
|
||||
**功能**:
|
||||
- 表格展示所有 Token
|
||||
- 搜索框(按名称过滤)
|
||||
- 下拉筛选(状态、权限)
|
||||
- 快速操作按钮(详情、启用/禁用、删除)
|
||||
- Token 列显示前 12 位,点击可复制完整 Token
|
||||
|
||||
#### 创建 Token 弹框
|
||||
|
||||
**触发**:点击 [+ 创建 Token] 按钮
|
||||
|
||||
**弹框内容**:
|
||||
```
|
||||
+-----------------------------------------------+
|
||||
| 创建 Token |
|
||||
+-----------------------------------------------+
|
||||
| Token 名称 * |
|
||||
| [_______________________________________] |
|
||||
| 用于识别客户端,如"生产服务器A" |
|
||||
| |
|
||||
| 权限范围 * |
|
||||
| ○ 只读(仅查询数据) |
|
||||
| ● 读写(可上传、删除数据) |
|
||||
| |
|
||||
| 过期设置 * |
|
||||
| ● 永久有效 |
|
||||
| ○ 30天后过期 |
|
||||
| ○ 90天后过期 |
|
||||
| ○ 自定义: [___] 天 |
|
||||
| |
|
||||
| [取消] [创建] |
|
||||
+-----------------------------------------------+
|
||||
```
|
||||
|
||||
**验证规则**:
|
||||
- Token 名称:必填,1-50 字符
|
||||
- 权限范围:必选
|
||||
- 过期设置:必选
|
||||
|
||||
**成功后**:
|
||||
- 关闭弹框
|
||||
- 显示新创建的 Token 详情弹框(包含完整 Token,提示复制保存)
|
||||
- 刷新列表
|
||||
|
||||
#### Token 详情弹框
|
||||
|
||||
**触发**:
|
||||
1. 点击列表中的 [详情] 按钮
|
||||
2. 创建 Token 成功后自动弹出
|
||||
|
||||
**弹框内容**:
|
||||
```
|
||||
+-----------------------------------------------+
|
||||
| Token 详情 |
|
||||
+-----------------------------------------------+
|
||||
| Token 值 |
|
||||
| [••••••••••••••••••••••••••••] [👁 显示] [📋 复制] |
|
||||
| |
|
||||
| 基本信息 |
|
||||
| 名称: 生产服务器A |
|
||||
| 权限: 只读 |
|
||||
| 状态: 🟢 启用中 |
|
||||
| 创建时间: 2026-09-13 10:30:00 |
|
||||
| 过期时间: 永久有效 |
|
||||
| |
|
||||
| 使用统计 |
|
||||
| 总请求数: 1,523 次 |
|
||||
| 最后使用: 2026-09-13 15:20:10 (5分钟前) |
|
||||
| 最后 IP: 192.168.1.100 |
|
||||
| 失败次数: 0 |
|
||||
| |
|
||||
| 访问日志 (最近 20 条) |
|
||||
| +-------------------------------------------+ |
|
||||
| | 时间 | IP | 操作 | 状态 | |
|
||||
| |------------------|--------------|---------|-----| |
|
||||
| | 15:20:10 | 192.168.1.100| GET ...| 200 | |
|
||||
| | 15:15:05 | 192.168.1.100| GET ...| 200 | |
|
||||
| +-------------------------------------------+ |
|
||||
| |
|
||||
| [关闭] [修改] [删除] |
|
||||
+-----------------------------------------------+
|
||||
```
|
||||
|
||||
**功能**:
|
||||
- Token 值默认遮罩,点击 [👁 显示] 切换显示/隐藏
|
||||
- [📋 复制] 按钮复制完整 Token
|
||||
- 状态图标:🟢 启用中 / 🔴 已禁用 / ⏰ 已过期
|
||||
- 访问日志表格可滚动
|
||||
- [修改] 按钮打开编辑弹框
|
||||
- [删除] 按钮触发删除确认
|
||||
|
||||
#### 编辑 Token 弹框
|
||||
|
||||
**触发**:点击详情弹框中的 [修改] 按钮
|
||||
|
||||
**弹框内容**:
|
||||
```
|
||||
+-----------------------------------------------+
|
||||
| 编辑 Token |
|
||||
+-----------------------------------------------+
|
||||
| Token 名称 * |
|
||||
| [生产服务器A_____________________________] |
|
||||
| |
|
||||
| 状态 |
|
||||
| ● 启用 |
|
||||
| ○ 禁用 |
|
||||
| |
|
||||
| [取消] [保存] |
|
||||
+-----------------------------------------------+
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- 权限和过期时间创建后不可修改
|
||||
- 只能修改名称和状态
|
||||
|
||||
#### 删除 Token 确认弹框
|
||||
|
||||
**触发**:点击 [删除] 按钮
|
||||
|
||||
**弹框内容**:
|
||||
```
|
||||
+-----------------------------------------------+
|
||||
| ⚠️ 删除 Token |
|
||||
+-----------------------------------------------+
|
||||
| 确认要删除以下 Token 吗? |
|
||||
| |
|
||||
| 名称: 生产服务器A |
|
||||
| Token: dss_a1b2c3... (前12位) |
|
||||
| |
|
||||
| ⚠️ 此操作不可恢复,使用此 Token 的客户端将无法访问 |
|
||||
| |
|
||||
| 输入主密码以确认: |
|
||||
| [_______________________________________] |
|
||||
| |
|
||||
| [取消] [确认删除] |
|
||||
+-----------------------------------------------+
|
||||
```
|
||||
|
||||
**验证**:
|
||||
- 必须输入正确的主密码(`admin123123123`)
|
||||
- 密码错误显示红色提示:"密码错误,请重试"
|
||||
|
||||
### 4.2 UI/UX 规范
|
||||
|
||||
#### 通知提示
|
||||
- **成功**:绿色,5 秒自动关闭
|
||||
- "✅ Token 创建成功"
|
||||
- "✅ Token 已禁用"
|
||||
- "✅ Token 已删除"
|
||||
- **错误**:红色,15 秒自动关闭
|
||||
- "❌ Token 名称不能为空"
|
||||
- "❌ 主密码错误"
|
||||
- "❌ Token 不存在"
|
||||
- **信息**:蓝色,8 秒自动关闭
|
||||
- "📋 Token 已复制到剪贴板"
|
||||
|
||||
#### 表单验证
|
||||
- 实时验证(输入时)
|
||||
- 错误时红框 + 聚焦
|
||||
- 验证失败不关闭弹框
|
||||
|
||||
#### 异步操作反馈
|
||||
- 按钮状态:`[创建]` → `[创建中...]` + 禁用
|
||||
- 操作开始时显示通知:"正在创建 Token..."
|
||||
- 完成后更新状态和通知
|
||||
|
||||
#### 颜色规范
|
||||
- 主色:`#667eea`(紫色)
|
||||
- 成功:`#10b981`(绿色)
|
||||
- 警告:`#f59e0b`(橙色)
|
||||
- 错误:`#ef4444`(红色)
|
||||
- 信息:`#3b82f6`(蓝色)
|
||||
|
||||
## 5. 实现技术栈
|
||||
|
||||
### 后端
|
||||
- **语言**:Lua (OpenResty)
|
||||
- **存储**:JSON 文件系统
|
||||
- **配置文件**:`nginx/nginx.conf`(需要修改)
|
||||
|
||||
### 前端
|
||||
- **框架**:纯 HTML/CSS/JavaScript(无框架依赖)
|
||||
- **样式**:参考现有 `web/index.html` 风格
|
||||
- **HTTP 客户端**:Fetch API
|
||||
|
||||
## 6. 实现步骤建议
|
||||
|
||||
### Phase 1: 后端 Token 验证逻辑
|
||||
1. 在 `nginx.conf` 中添加 Token 验证函数
|
||||
2. 修改现有 API 路由,增加 `X-Token` 认证支持
|
||||
3. 实现权限检查(readonly vs readwrite)
|
||||
4. 保留 `X-Password` 向后兼容
|
||||
|
||||
### Phase 2: Token 管理 API
|
||||
1. 实现 `POST /api/tokens` 创建 Token
|
||||
2. 实现 `GET /api/tokens` 列出所有 Token
|
||||
3. 实现 `GET /api/tokens/:token` 获取详情
|
||||
4. 实现 `PATCH /api/tokens/:token` 更新状态
|
||||
5. 实现 `DELETE /api/tokens/:token` 删除 Token
|
||||
|
||||
### Phase 3: 审计和安全机制
|
||||
1. 记录每次 Token 使用(时间、IP、操作)
|
||||
2. 实现限流逻辑(60次/分钟)
|
||||
3. 实现失败次数统计和自动禁用
|
||||
4. 实现过期检测
|
||||
|
||||
### Phase 4: Web 界面
|
||||
1. 在现有 `web/index.html` 顶部添加导航切换
|
||||
2. 创建 Token 管理页面(列表 + 搜索过滤)
|
||||
3. 实现创建 Token 弹框
|
||||
4. 实现 Token 详情弹框
|
||||
5. 实现编辑和删除功能
|
||||
|
||||
### Phase 5: 测试和文档
|
||||
1. 手动测试所有 API 端点
|
||||
2. 验证权限控制和安全机制
|
||||
3. 更新 README.md 文档
|
||||
4. 提供 Token 使用示例
|
||||
|
||||
## 7. 向后兼容性
|
||||
|
||||
### 现有客户端
|
||||
- 使用 `X-Password: admin123123123` 的现有脚本和工具继续正常工作
|
||||
- 无需立即迁移到 Token 机制
|
||||
|
||||
### 迁移路径
|
||||
1. 部署新版本(增加 Token 功能)
|
||||
2. 在 Web 界面创建新 Token
|
||||
3. 逐步更新客户端配置(从 `X-Password` 改为 `X-Token`)
|
||||
4. 最终可选择性禁用 `X-Password`(配置开关)
|
||||
|
||||
## 8. 测试用例
|
||||
|
||||
### API 测试
|
||||
```bash
|
||||
# 1. 创建 Token
|
||||
curl -X POST http://localhost:5001/api/tokens \
|
||||
-H "X-Password: admin123123123" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"测试Token","permission":"readonly","expires_in":null}'
|
||||
|
||||
# 2. 使用 Token 获取数据
|
||||
curl http://localhost:5001/api/data/weibo:ykaayk \
|
||||
-H "X-Token: dss_xxxxx"
|
||||
|
||||
# 3. 测试只读权限(应该失败)
|
||||
curl -X POST http://localhost:5001/api/data \
|
||||
-H "X-Token: dss_xxxxx" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"tag":"test","type":"token","data":{}}'
|
||||
|
||||
# 4. 列出所有 Token
|
||||
curl http://localhost:5001/api/tokens \
|
||||
-H "X-Password: admin123123123"
|
||||
|
||||
# 5. 禁用 Token
|
||||
curl -X PATCH http://localhost:5001/api/tokens/dss_xxxxx \
|
||||
-H "X-Password: admin123123123" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"status":"disabled"}'
|
||||
|
||||
# 6. 删除 Token
|
||||
curl -X DELETE http://localhost:5001/api/tokens/dss_xxxxx \
|
||||
-H "X-Password: admin123123123" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"confirm_password":"admin123123123"}'
|
||||
```
|
||||
|
||||
## 9. 验收标准
|
||||
|
||||
### 功能验收
|
||||
- ✅ 可以通过 Web 界面创建 Token
|
||||
- ✅ 创建后显示完整 Token 值(一次性展示)
|
||||
- ✅ Token 列表正确显示所有 Token 及其状态
|
||||
- ✅ 只读 Token 无法执行写操作
|
||||
- ✅ 读写 Token 可以执行所有操作
|
||||
- ✅ 访问日志正确记录(时间、IP、操作、状态)
|
||||
- ✅ 限流生效(60次/分钟)
|
||||
- ✅ 连续失败 5 次自动禁用
|
||||
- ✅ 过期 Token 无法使用
|
||||
- ✅ 删除 Token 需要二次确认
|
||||
- ✅ 旧的 `X-Password` 认证继续工作
|
||||
|
||||
### UI/UX 验收
|
||||
- ✅ 所有弹框居中显示,带遮罩层
|
||||
- ✅ 表单验证实时生效,红框 + 聚焦
|
||||
- ✅ 异步操作有加载状态和通知
|
||||
- ✅ 通知自动关闭(成功5秒,错误15秒)
|
||||
- ✅ Token 值支持显示/隐藏切换
|
||||
- ✅ 点击复制成功后有反馈
|
||||
- ✅ 响应式布局,移动端友好
|
||||
|
||||
### 安全验收
|
||||
- ✅ Token 存储在服务器端,前端只展示一次
|
||||
- ✅ 主密码验证正确(创建、删除时)
|
||||
- ✅ 限流正确拦截过多请求
|
||||
- ✅ 失败次数统计准确
|
||||
- ✅ 权限控制无漏洞
|
||||
|
||||
## 10. 附录:错误码对照表
|
||||
|
||||
| 状态码 | 错误信息 | 场景 |
|
||||
|--------|---------|------|
|
||||
| 200 | - | 请求成功 |
|
||||
| 400 | Invalid request | 请求参数错误 |
|
||||
| 401 | Invalid token | Token 不存在或无效 |
|
||||
| 401 | Token disabled | Token 已被禁用 |
|
||||
| 401 | Token expired | Token 已过期 |
|
||||
| 403 | Permission denied | 权限不足(只读 Token 尝试写操作)|
|
||||
| 404 | Token not found | Token 不存在 |
|
||||
| 429 | Rate limit exceeded | 超过限流限制 |
|
||||
| 500 | Internal server error | 服务器内部错误 |
|
||||
|
||||
---
|
||||
|
||||
**文档版本**:v1.0
|
||||
**创建日期**:2026-09-13
|
||||
**作者**:Hermes AI Agent
|
||||
**项目路径**:`/home/hermes/projects/data-sync-service`
|
||||
Reference in new issue
Block a user