Files
leaudit-platform-frontend/docs/URGENT-前端必须修改.md
T
TanWenyan 63acabccc9 配置优化:切换到生产环境内网地址并添加Dify前端修改文档
1. 更新API配置:梅州端口51703切换到内网地址172.16.0.55:8073
2. 测试环境切换到正确的端口8873
3. 启动脚本改用生产模式:start:pm2:production:multi
4. 添加紧急修改文档:URGENT-前端必须修改.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 11:14:43 +08:00

399 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🚨 紧急:前端Dify集成问题修复指南
## 问题现状
**当前错误**
```javascript
// ❌ 错误的Authorization头
Authorization: Bearer app-lHn5EmeACIaLjG9yz0rYIFfM // 这是Dify API Key,不是JWT
// ❌ 错误的user字段
user: "user_34a1d450-6a24-4db7-b1e7-8dd7c0876f14:sess_3z84y7dtuhr" // UUID格式
```
**导致的问题**
1. 无法加载历史对话记录(user不匹配)
2. 对话没有按用户隔离(所有人共享对话)
3. 安全问题(API Key暴露在前端)
---
## 🎯 必须修改的3个地方
### 修改1: Authorization头 - 使用JWT替代Dify API Key
#### ❌ 旧代码(错误)
```typescript
// app/services/dify-client.server.ts 或类似文件
const DIFY_API_KEY = "app-lHn5EmeACIaLjG9yz0rYIFfM";
async function callDifyAPI(endpoint: string, data: any) {
const response = await fetch(`${DIFY_BASE_URL}${endpoint}`, {
headers: {
'Authorization': `Bearer ${DIFY_API_KEY}`, // ❌ 错误!暴露API Key
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
return response.json();
}
```
#### ✅ 新代码(正确)
```typescript
// app/services/dify-client.server.ts
// 1. 移除DIFY_API_KEY配置
// const DIFY_API_KEY = "..."; // 删除这行
// 2. 从用户session获取JWT
import { getUserSession } from "~/api/login/auth.server";
async function callDifyAPI(request: Request, endpoint: string, data: any) {
// 获取JWT
const { frontendJWT } = await getUserSession(request);
if (!frontendJWT) {
throw new Error("未登录,请先登录");
}
// 使用JWT作为Authorization头
const response = await fetch(`http://172.16.0.55:8000/dify${endpoint}`, {
headers: {
'Authorization': `Bearer ${frontendJWT}`, // ✅ 正确!使用JWT
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
return response.json();
}
```
### 修改2: 请求URL - 指向FastAPI代理而非直连Dify
#### ❌ 旧代码(错误)
```typescript
// 直连Dify API
const DIFY_BASE_URL = "http://nas.7bm.co:12980/v1";
// 示例:获取会话列表
const response = await fetch(
`${DIFY_BASE_URL}/conversations?user=${user}&limit=100`,
// ...
);
```
#### ✅ 新代码(正确)
```typescript
// 通过FastAPI代理访问Dify
const API_BASE_URL = "http://172.16.0.55:8000"; // FastAPI地址
// 示例:获取会话列表
const response = await fetch(
`${API_BASE_URL}/dify/conversations?limit=100`, // ✅ 走/dify代理,不传user
{
headers: {
'Authorization': `Bearer ${frontendJWT}` // ✅ 使用JWT
}
}
);
```
### 修改3: user字段 - 完全移除,让后端自动添加
#### ❌ 旧代码(错误)
```typescript
// 生成UUID格式的user
function generateUserId() {
return `user_${crypto.randomUUID()}:sess_${randomString()}`;
}
// 发送消息
const data = {
query: "你好",
user: generateUserId(), // ❌ 错误!UUID格式
conversation_id: null,
response_mode: "streaming",
inputs: {}
};
```
#### ✅ 新代码(正确)
```typescript
// 完全不传user字段,后端会自动添加JWT的username
const data = {
query: "你好",
// user字段完全不传! ✅ 正确
conversation_id: null,
response_mode: "streaming",
inputs: {}
};
```
---
## 📝 完整的修改示例
### 示例1: 获取会话列表
#### ❌ 旧代码
```typescript
// app/routes/api.conversations.tsx
export async function loader({ request }: LoaderFunctionArgs) {
const url = new URL(request.url);
const user = url.searchParams.get("user") || generateUserId();
const limit = url.searchParams.get("limit") || "100";
const response = await fetch(
`http://nas.7bm.co:12980/v1/conversations?user=${user}&limit=${limit}`,
{
headers: {
'Authorization': `Bearer app-lHn5EmeACIaLjG9yz0rYIFfM`, // ❌ Dify API Key
'Content-Type': 'application/json'
}
}
);
return json(await response.json());
}
```
#### ✅ 新代码
```typescript
// app/routes/api.conversations.tsx
import { getUserSession } from "~/api/login/auth.server";
export async function loader({ request }: LoaderFunctionArgs) {
// 1. 获取JWT
const { frontendJWT } = await getUserSession(request);
if (!frontendJWT) {
return json({ error: "未登录" }, { status: 401 });
}
// 2. 调用FastAPI代理(不传user,后端自动添加)
const url = new URL(request.url);
const limit = url.searchParams.get("limit") || "100";
const response = await fetch(
`http://172.16.0.55:8000/dify/conversations?limit=${limit}`, // ✅ 走代理
{
headers: {
'Authorization': `Bearer ${frontendJWT}`, // ✅ 使用JWT
'Content-Type': 'application/json'
}
}
);
return json(await response.json());
}
```
### 示例2: 发送消息
#### ❌ 旧代码
```typescript
// app/routes/api.chat-messages.tsx
export async function action({ request }: ActionFunctionArgs) {
const body = await request.json();
const response = await fetch(
`http://nas.7bm.co:12980/v1/chat-messages`,
{
method: 'POST',
headers: {
'Authorization': `Bearer app-lHn5EmeACIaLjG9yz0rYIFfM`, // ❌ Dify API Key
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: body.query,
user: body.user || generateUserId(), // ❌ UUID格式
conversation_id: body.conversation_id,
response_mode: "streaming",
inputs: body.inputs || {}
})
}
);
return new Response(response.body, {
headers: { 'Content-Type': 'text/event-stream' }
});
}
```
#### ✅ 新代码
```typescript
// app/routes/api.chat-messages.tsx
import { getUserSession } from "~/api/login/auth.server";
export async function action({ request }: ActionFunctionArgs) {
// 1. 获取JWT
const { frontendJWT } = await getUserSession(request);
if (!frontendJWT) {
return json({ error: "未登录" }, { status: 401 });
}
// 2. 解析请求体
const body = await request.json();
// 3. 调用FastAPI代理(不传user,后端自动添加)
const response = await fetch(
`http://172.16.0.55:8000/dify/chat-messages`, // ✅ 走代理
{
method: 'POST',
headers: {
'Authorization': `Bearer ${frontendJWT}`, // ✅ 使用JWT
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: body.query,
// user字段完全不传 ✅ 后端自动添加
conversation_id: body.conversation_id,
response_mode: "streaming",
inputs: body.inputs || {}
})
}
);
return new Response(response.body, {
headers: { 'Content-Type': 'text/event-stream' }
});
}
```
---
## 🔍 检查清单
### 前端开发者必须检查的文件
1. **Dify客户端配置文件**
- 位置:`app/services/dify-client.server.ts` 或类似
- 检查:是否还有`DIFY_API_KEY`定义?(应该删除)
- 检查:是否还有`DIFY_BASE_URL = "http://nas.7bm.co:12980"`?(应改为FastAPI地址)
2. **API路由文件**
- 位置:`app/routes/api.*.tsx` 中所有与Dify相关的
- 检查:所有`fetch`调用是否指向`http://172.16.0.55:8000/dify/*`
- 检查:所有`Authorization`头是否使用`frontendJWT`
3. **user字段生成逻辑**
- 搜索关键字:`generateUserId`, `user_`, `crypto.randomUUID`
- 检查:是否还在生成UUID格式的user?(应该完全移除)
4. **环境变量配置**
- 位置:`.env``.env.local`
- 检查:是否还有`DIFY_API_KEY``NEXT_PUBLIC_APP_KEY`?(应该删除)
---
## 🧪 验证方法
修改完成后,使用浏览器开发者工具验证:
### 1. 检查Authorization头
打开 Network 标签,找到Dify相关请求:
**✅ 正确的请求头**
```
Request URL: http://172.16.0.55:8000/dify/conversations?limit=100
Request Headers:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... (JWT格式,很长)
Content-Type: application/json
```
**❌ 错误的请求头**
```
Request URL: http://nas.7bm.co:12980/v1/conversations?user=xxx
Request Headers:
Authorization: Bearer app-lHn5EmeACIaLjG9yz0rYIFfM (Dify API Key,很短)
```
### 2. 检查请求体
对于POST请求(如发送消息):
**✅ 正确的请求体**
```json
{
"query": "你好",
"conversation_id": null,
"response_mode": "streaming",
"inputs": {}
}
```
注意:**没有user字段**
**❌ 错误的请求体**
```json
{
"query": "你好",
"user": "user_34a1d450-6a24-4db7-b1e7-8dd7c0876f14:sess_xxx",
"conversation_id": null,
"response_mode": "streaming",
"inputs": {}
}
```
### 3. 检查后端日志
修改后,后端日志应该显示:
```log
[INFO] Dify请求用户: admin (ID: 5, 路径: conversations)
[INFO] 自动添加user参数: admin
[INFO] 查询参数: {'user': 'admin', 'limit': '100'}
```
### 4. 检查Dify后台
在Dify管理界面的对话列表中,应该看到:
- 新对话的用户显示为:`admin`(或实际的username
- 不再是:`user_34a1d450...`
---
## ⚠️ 常见错误
### 错误1: 前端仍使用DIFY_API_KEY
**症状**Authorization头是`Bearer app-xxx`(短字符串)
**解决**:删除所有`DIFY_API_KEY`定义,改用`frontendJWT`
### 错误2: 前端直连Dify
**症状**:请求URL是`http://nas.7bm.co:12980/v1/...`
**解决**:所有URL改为`http://172.16.0.55:8000/dify/...`
### 错误3: 仍在传递UUID格式的user
**症状**:请求体包含`"user": "user_34a1d450..."`
**解决**:完全删除user字段,不要传递
### 错误4: JWT获取失败
**症状**`frontendJWT``null``undefined`
**解决**:检查`getUserSession`导入路径和session配置
---
## 📋 修改总结
| 项目 | 旧值 | 新值 |
|------|------|------|
| Authorization头 | `Bearer app-lHn5EmeACIaLjG9yz0rYIFfM` | `Bearer {frontendJWT}` |
| 请求URL | `http://nas.7bm.co:12980/v1/*` | `http://172.16.0.55:8000/dify/*` |
| user字段 | `user_34a1d450-...` | 完全不传(后端自动添加) |
---
## 🎯 期望结果
修改完成后:
- ✅ 每个用户只能看到自己的对话记录
- ✅ Dify后台显示真实的username(如admin
- ✅ API Key不再暴露在前端
- ✅ 所有对话按用户隔离
- ✅ 历史对话记录正常加载
---
**紧急程度**: 🔴 高优先级
**预计修改时间**: 30-60分钟
**影响范围**: 所有Dify相关功能
**联系后端**: 如有疑问,请查看`docs/dify-frontend-user-field-guide.md`获取更多细节