Files
leaudit-platform-frontend/docs/dify-frontend-modification-summary.md
T
TanWenyan c4c08cb59b 重构Dify客户端:改为通过FastAPI代理并使用JWT认证
主要变更:
- 修改 dify-client.server.ts 使用 JWT 认证通过 FastAPI 后端代理访问 Dify API
- 所有 Dify API 路由(chat-messages, parameters, conversations, messages)添加 JWT 获取和传递逻辑
- API_URL 从直连 Dify 改为 FastAPI 后端的 /dify 路由
- 增强 JWT 认证失败的错误处理(返回401状态码)
- 添加详细的日志输出,便于调试

安全提升:
- DIFY_API_KEY 从前端移至后端,不再暴露在客户端代码
- 使用统一的 JWT 认证体系,提高系统安全性

文档:
- 新增 dify-proxy-backend-integration.md - 后端对接文档(包含完整 FastAPI 实现示例)
- 新增 dify-frontend-modification-summary.md - 前端修改总结
- 新增 CLAUDE.md - 项目架构说明文档

影响范围:
- app/services/dify-client.server.ts - 核心服务层
- app/routes/api.chat-messages.tsx - 聊天消息
- app/routes/api.parameters.tsx - 应用参数
- app/routes/api.conversations.tsx - 会话列表
- app/routes/api.messages.tsx - 消息历史
- app/routes/api.conversations.$id.tsx - 删除会话
- app/routes/api.conversations.$id.name.tsx - 重命名会话

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 09:47:48 +08:00

7.2 KiB
Raw Blame History

Dify 客户端 JWT 认证改造 - 前端修改总结

📅 修改信息

  • 修改日期: 2025-01-XX
  • 版本: v2.0 - JWT 认证版本
  • 修改类型: 架构升级 - 从直连改为代理模式

🎯 修改目标

将 Dify AI 服务调用从 前端直连 改为 通过 FastAPI 后端代理,并使用 JWT 认证替代原有的 API KEY。


📋 核心变更

架构变更

旧: 前端 → Dify API (使用 API_KEY)
新: 前端 → FastAPI 后端 (使用 JWT) → Dify API (使用 API_KEY)

认证方式变更

旧: Authorization: Bearer {DIFY_API_KEY}
新: Authorization: Bearer {frontendJWT}

API 端点变更

旧: https://api.dify.ai/v1/chat-messages
新: http://172.16.0.55:8000/dify/chat-messages

📁 修改的文件清单

1. 核心服务层 (1 个文件)

  • app/services/dify-client.server.ts - Dify 客户端核心

主要修改

  • 导入 API_BASE_URL 从配置文件
  • DIFY_CONFIG.API_URL 改为 ${API_BASE_URL}/dify
  • difyFetch 函数添加 jwt 参数
  • 所有 client 方法添加 jwt? 参数
  • 添加 401 错误处理(JWT 认证失败)

2. API 路由层 (6 个文件)

所有路由都添加了 JWT 获取、验证和传递逻辑:

  • app/routes/api.chat-messages.tsx - 聊天消息发送
  • app/routes/api.parameters.tsx - 应用参数获取
  • app/routes/api.conversations.tsx - 会话列表获取
  • app/routes/api.messages.tsx - 会话消息历史
  • app/routes/api.conversations.$id.tsx - 会话删除
  • app/routes/api.conversations.$id.name.tsx - 会话重命名

统一修改模式

// 1. 获取 JWT
const { getUserSession } = await import("~/api/login/auth.server");
const { frontendJWT } = await getUserSession(request);

// 2. JWT 验证
if (!frontendJWT) {
    return json({ error: 'JWT认证失败,请重新登录' }, { status: 401 });
}

// 3. 传递给 difyClient
await difyClient.method(..., frontendJWT);

// 4. 错误处理
const status = error.message?.includes('JWT认证失败') ? 401 : 500;

🔐 配置迁移说明

前端配置(已废弃)

# .env - 这些配置不再使用
NEXT_PUBLIC_APP_ID=http://nas.7bm.co:12980/app/46539478-3281-4e98-a445-6da9dc078e95/configuration
NEXT_PUBLIC_APP_KEY=app-N3su9tKyMMnqxt2EMgOkVof7

后端配置(需要添加)

这些配置应该移到 FastAPI 后端

# FastAPI 环境变量配置
DIFY_API_URL = "http://nas.7bm.co:12980/v1"
DIFY_API_KEY = "app-N3su9tKyMMnqxt2EMgOkVof7"
DIFY_APP_ID = "46539478-3281-4e98-a445-6da9dc078e95"

前端新配置

# .env - 前端只需要配置 FastAPI 地址
API_BASE_URL=http://172.16.0.55:8000

🛣️ 后端需要实现的路由

路由 方法 说明
/dify/parameters GET 获取应用参数
/dify/conversations GET 获取会话列表
/dify/messages GET 获取会话消息历史
/dify/chat-messages POST 发送聊天消息(支持流式)
/dify/conversations/{id}/name POST 重命名会话
/dify/conversations/{id} DELETE 删除会话
/dify/messages/{id}/feedbacks POST 消息反馈

详细对接文档: docs/dify-proxy-backend-integration.md


⚠️ 关键注意事项

1. JWT 认证必须实现

  • 所有请求都携带 Authorization: Bearer {JWT}
  • JWT 验证失败必须返回 401 状态码
  • 错误格式:{"error": "JWT认证失败,请重新登录"}

2. 流式响应必须支持

  • /dify/chat-messages 接口支持流式响应(SSE
  • 响应头:Content-Type: text/event-stream
  • 不能缓冲,必须实时转发

3. 配置安全

  • DIFY_API_KEY 只能存在后端
  • 前端代码中不再包含任何 Dify 凭据
  • 所有敏感配置通过环境变量管理

4. 错误处理

  • JWT 不存在: 401
  • JWT 过期/无效: 401
  • 其他错误: 500

🧪 测试清单

前端测试

  • 聊天消息发送(流式)
  • 聊天消息发送(非流式)
  • 会话列表加载
  • 会话切换和消息历史
  • 会话重命名
  • 会话删除
  • JWT 过期后跳转登录

后端测试

  • JWT 验证逻辑
  • 所有 API 路由返回正确
  • 流式响应正常工作
  • 错误返回正确状态码
  • 日志记录完整

📊 代码统计

  • 修改文件数: 7 个
  • 新增代码行数: ~150 行
  • 修改代码行数: ~200 行
  • 核心逻辑变更: 认证方式 + API 端点

🚀 部署步骤

1. 后端准备

# 1. 在 FastAPI 中实现 /dify/* 路由
# 2. 配置 Dify API 凭据
# 3. 集成 JWT 验证逻辑
# 4. 测试所有接口

2. 前端部署

# 1. 确认后端已就绪
npm run build
npm run start

3. 联调测试

# 1. 测试聊天功能
# 2. 测试会话管理
# 3. 测试 JWT 过期处理
# 4. 检查日志输出

📝 代码示例

前端调用示例

// app/routes/api.chat-messages.tsx
const { getUserSession } = await import("~/api/login/auth.server");
const { frontendJWT } = await getUserSession(request);

const response = await difyClient.createChatMessage(
    inputs,
    query,
    user,
    responseMode,
    conversationId,
    files,
    frontendJWT  // 传递 JWT
);

后端实现示例

# FastAPI 路由
@app.post("/dify/chat-messages")
async def create_chat_message(
    request: Request,
    authorization: str = Header(None)
):
    # 1. 验证 JWT
    jwt_token = authorization.replace("Bearer ", "")
    user_info = verify_jwt(jwt_token)

    if not user_info:
        raise HTTPException(status_code=401, detail="JWT认证失败")

    # 2. 调用 Dify API
    headers = {"Authorization": f"Bearer {DIFY_API_KEY}"}
    body = await request.json()

    # 3. 转发流式响应
    if body.get("response_mode") == "streaming":
        return StreamingResponse(...)

📞 支持与文档

详细文档

  • 后端对接文档: docs/dify-proxy-backend-integration.md
  • JWT 实现文档: docs/JWT_IMPLEMENTATION.md
  • CLAUDE.md: 项目总体架构说明

相关链接


检查清单

前端(已完成)

  • dify-client.server.ts 修改
  • 所有 API 路由添加 JWT
  • 错误处理完善
  • 日志输出优化
  • 配置迁移说明

后端(待实现)

  • /dify/* 路由实现
  • JWT 验证集成
  • 流式响应支持
  • 错误处理规范
  • 日志记录完善
  • CORS 配置(如需)

联调测试(待完成)

  • 基础功能测试
  • JWT 认证测试
  • 流式响应测试
  • 错误处理测试
  • 性能测试

🎉 总结

本次修改完成了 Dify 服务调用的架构升级:

  • 安全性提升: API KEY 不再暴露在前端
  • 统一认证: 使用项目统一的 JWT 认证体系
  • 便于管理: 所有 Dify 配置集中在后端
  • 向后兼容: 保留了原有的 API 接口设计

下一步: 等待后端实现完成后进行联调测试。


修改完成日期: 2025-01-XX 文档版本: v1.0