283 lines
6.6 KiB
Markdown
283 lines
6.6 KiB
Markdown
# 混合方案安全性说明
|
||
|
||
## 📋 当前实现的安全特性
|
||
|
||
### 1️⃣ 核心算法保护 ✅
|
||
|
||
**问题:** 如何防止客户端看到核心算法?
|
||
|
||
**解决:**
|
||
- ✅ 核心计算逻辑在服务器端执行
|
||
- ✅ 客户端只能看到输入和输出,看不到计算过程
|
||
- ✅ 即使客户端打开开发者工具,也无法获取算法
|
||
|
||
```python
|
||
# 🔒 服务器端(客户端看不到)
|
||
def calculate_expression(request):
|
||
# 这里的算法逻辑客户端完全看不到
|
||
result = eval(expression) # 可以替换成复杂的 AI 模型
|
||
return result
|
||
```
|
||
|
||
---
|
||
|
||
### 2️⃣ 输入验证 ✅
|
||
|
||
**问题:** 如何防止恶意输入?
|
||
|
||
**解决:**
|
||
- ✅ 正则表达式验证:只允许数字和基本运算符
|
||
- ✅ 拒绝危险字符和代码注入
|
||
|
||
```python
|
||
# 安全检查
|
||
if not re.match(r'^[\d\s\+\-\*\/\(\)\.]+$', expression):
|
||
return "非法输入"
|
||
```
|
||
|
||
**可接受:** `87-98`, `100+200`, `(10*5)/2`
|
||
**拒绝:** `__import__('os')`, `exec('code')`, `sys.exit()`
|
||
|
||
---
|
||
|
||
### 3️⃣ 详细日志 ✅
|
||
|
||
**功能:** 监控所有请求和响应
|
||
|
||
**日志内容:**
|
||
```
|
||
============================================================
|
||
📥 收到计算请求
|
||
时间: 2024-12-16 15:30:45
|
||
表达式: 87-98
|
||
API Key: 未提供(无鉴权模式)
|
||
============================================================
|
||
🛡️ 安全检查: 验证表达式格式...
|
||
✅ 表达式格式验证通过
|
||
🔒 开始执行核心算法...
|
||
✅ 计算完成: 87-98 = -11
|
||
============================================================
|
||
📤 返回计算结果
|
||
成功: True
|
||
表达式: 87-98
|
||
结果: -11.0
|
||
消息: 计算成功: 87-98 = -11
|
||
============================================================
|
||
```
|
||
|
||
---
|
||
|
||
### 4️⃣ API Key 鉴权(可选)🔐
|
||
|
||
**当前状态:** 已准备好,但默认关闭
|
||
|
||
#### 如何启用 API Key 验证?
|
||
|
||
**步骤 1:在后端取消注释**
|
||
|
||
打开 `Server/app/api/v1/jsx_demo.py`,取消注释这段代码:
|
||
|
||
```python
|
||
# 取消注释下面这段
|
||
if x_api_key not in VALID_API_KEYS:
|
||
logger.warning("❌ API Key 验证失败")
|
||
raise HTTPException(status_code=403, detail="无效的 API Key")
|
||
logger.info("✅ API Key 验证通过")
|
||
```
|
||
|
||
**步骤 2:在前端添加 API Key**
|
||
|
||
打开 `Designer/src/api/jsxApi/inline/hybrid-demo.ts`:
|
||
|
||
```typescript
|
||
const response = await fetch(`${config.apiBaseUrl}/jsx_demo/calculate`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'X-API-Key': 'demo_key_123' // 添加这行
|
||
},
|
||
body: JSON.stringify({
|
||
expression: layerName
|
||
})
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## 🔐 安全级别对比
|
||
|
||
### ❌ 纯前端方案(不安全)
|
||
|
||
```typescript
|
||
// 客户端代码(所有人都能看到)
|
||
const result = complexAlgorithm(input); // ⚠️ 算法暴露
|
||
const jsx = `var layer = doc.artLayers.add(); ...`;
|
||
```
|
||
|
||
**风险:**
|
||
- ❌ 核心算法完全暴露
|
||
- ❌ 可以轻松复制算法
|
||
- ❌ 可以绕过任何验证
|
||
|
||
---
|
||
|
||
### ✅ 混合方案(当前实现)
|
||
|
||
```typescript
|
||
// 客户端只发送请求
|
||
const result = await fetch('/calculate', { expression: '87-98' });
|
||
// 只能看到返回的结果,看不到计算过程
|
||
```
|
||
|
||
**优势:**
|
||
- ✅ 核心算法在服务器,客户端看不到
|
||
- ✅ 输入验证防止注入攻击
|
||
- ✅ 详细日志监控所有请求
|
||
|
||
---
|
||
|
||
### 🔐 混合方案 + API Key(高级)
|
||
|
||
```typescript
|
||
// 客户端需要提供 API Key
|
||
const result = await fetch('/calculate', {
|
||
headers: { 'X-API-Key': 'your_secret_key' },
|
||
body: { expression: '87-98' }
|
||
});
|
||
```
|
||
|
||
**优势:**
|
||
- ✅ 以上所有优势
|
||
- ✅ 只有授权客户端可以调用
|
||
- ✅ 可以限制每个 Key 的调用次数
|
||
- ✅ 可以追踪谁在使用 API
|
||
|
||
---
|
||
|
||
## 💡 进一步加强建议
|
||
|
||
### 1. 加密传输(HTTPS)
|
||
```bash
|
||
# 使用 SSL 证书
|
||
uvicorn app.main:app --ssl-keyfile=key.pem --ssl-certfile=cert.pem
|
||
```
|
||
|
||
### 2. 限流(Rate Limiting)
|
||
```python
|
||
from slowapi import Limiter
|
||
limiter = Limiter(key_func=get_remote_address)
|
||
|
||
@limiter.limit("10/minute") # 每分钟最多 10 次请求
|
||
@router.post("/calculate")
|
||
async def calculate_expression(...):
|
||
...
|
||
```
|
||
|
||
### 3. IP 白名单
|
||
```python
|
||
ALLOWED_IPS = {"127.0.0.1", "192.168.1.100"}
|
||
|
||
@router.post("/calculate")
|
||
async def calculate_expression(request: Request):
|
||
if request.client.host not in ALLOWED_IPS:
|
||
raise HTTPException(403, "IP 未授权")
|
||
```
|
||
|
||
### 4. 结果缓存
|
||
```python
|
||
from functools import lru_cache
|
||
|
||
@lru_cache(maxsize=1000)
|
||
def calculate(expression: str):
|
||
# 相同的表达式不重复计算
|
||
return eval(expression)
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 总结
|
||
|
||
| 特性 | 状态 | 说明 |
|
||
|------|------|------|
|
||
| 核心算法保护 | ✅ 已实现 | 算法在服务器端,客户端看不到 |
|
||
| 输入验证 | ✅ 已实现 | 正则表达式过滤危险输入 |
|
||
| 详细日志 | ✅ 已实现 | 记录所有请求和响应 |
|
||
| API Key 鉴权 | 🔧 可选 | 默认关闭,取消注释即可启用 |
|
||
| HTTPS 加密 | ⚠️ 推荐 | 生产环境必须启用 |
|
||
| 限流保护 | ⚠️ 推荐 | 防止恶意刷接口 |
|
||
|
||
---
|
||
|
||
## 🚀 测试安全性
|
||
|
||
### 测试 1:查看网络请求
|
||
|
||
1. 打开浏览器开发者工具(F12)
|
||
2. 切换到 Network 标签
|
||
3. 点击"智能配色"按钮
|
||
4. 查看请求详情
|
||
|
||
**你只能看到:**
|
||
- ✅ 请求 URL:`/api/v1/jsx_demo/calculate`
|
||
- ✅ 请求参数:`{"expression": "87-98"}`
|
||
- ✅ 响应结果:`{"success": true, "result": -11}`
|
||
|
||
**你看不到:**
|
||
- ❌ 服务器端的计算逻辑
|
||
- ❌ 核心算法代码
|
||
- ❌ 其他用户的请求
|
||
|
||
---
|
||
|
||
### 测试 2:尝试注入攻击
|
||
|
||
尝试创建一个图层,名称为:`__import__('os').system('rm -rf /')`
|
||
|
||
**预期结果:**
|
||
- ❌ 被拒绝
|
||
- 📝 日志显示:`表达式包含非法字符`
|
||
- 🛡️ 系统安全
|
||
|
||
---
|
||
|
||
### 测试 3:查看服务器日志
|
||
|
||
运行 Demo 后,查看后端控制台输出,应该看到详细的日志:
|
||
|
||
```bash
|
||
cd Server
|
||
python -m uvicorn app.main:app --reload
|
||
```
|
||
|
||
**日志示例:**
|
||
```
|
||
2024-12-16 15:30:45 [INFO] ============================================================
|
||
2024-12-16 15:30:45 [INFO] 📥 收到计算请求
|
||
2024-12-16 15:30:45 [INFO] 时间: 2024-12-16 15:30:45
|
||
2024-12-16 15:30:45 [INFO] 表达式: 87-98
|
||
2024-12-16 15:30:45 [INFO] API Key: 未提供(无鉴权模式)
|
||
...
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 最佳实践建议
|
||
|
||
### 开发阶段(当前)
|
||
- ✅ 无 API Key(方便测试)
|
||
- ✅ 详细日志
|
||
- ✅ HTTP 即可
|
||
|
||
### 生产环境
|
||
- 🔐 启用 API Key
|
||
- 🔒 启用 HTTPS
|
||
- 📊 启用限流
|
||
- 📝 日志写入文件
|
||
- 🛡️ IP 白名单(可选)
|
||
|
||
---
|
||
|
||
**安全性总结:**
|
||
当前方案已经实现了**核心算法保护**,客户端无法看到服务器端的计算逻辑。如需进一步加强,可以启用 API Key 验证和其他安全措施。
|
||
|