
Dify Chat API 代理层实现原理如何安全调用 Dify API 而不暴露密钥的完整方案【免费下载链接】dify-app-hub一个 Dify 应用管理平台基于 Dify API 构建提供深度优化的用户端交互界面支持 Chatflow、Workflow 等多种 Dify 应用类型适配深度思考、思维链、图表渲染、文件处理等丰富的 AI 输出形式提供开箱即用的 AI 应用解决方案。项目地址: https://gitcode.com/gh_mirrors/di/dify-app-hub如果你曾在前端直接接入Dify Chat API一定踩过一个坑Dify API Key 一旦写进浏览器端代码任何人打开 DevTools 或反编译 JS 就能拿到密钥。开源项目dify-app-hub一个 Dify 应用管理平台通过一层Dify API 代理层彻底解决了这个问题前端只与平台自身的接口通信密钥保存在服务端数据库请求由服务端注入密钥后转发给 Dify。本文带你拆解这个代理层的完整实现帮你快速掌握安全调用 Dify API 而不暴露密钥的工程化方案。为什么需要 Dify API 代理层把 Dify API Key 放在客户端有三个典型风险密钥泄露API Key 会出现在 JS 打包产物、请求头和网络面板中等于公开跨域限制Dify 服务端对来源有访问控制浏览器直连容易受 CORS 约束️多应用难管理Chatflow、Workflow 等多种应用类型各自一个 Key分散在前端配置中无法统一管控。Dify 官方在 API 文档中也明确提示强烈建议将 API Key 放在后端服务中而非直接放在客户端程序里。下图是 Dify 访问 API 页面中获取基础 URL 与 Key 安全提示的位置代理层正是针对这些痛点设计的中间人浏览器 → 平台代理接口 → Dify API密钥全程不出服务端。代理层总体架构三层分离dify-app-hub 的调用链路非常清晰分三层层级位置职责前端封装层web/lib/dify-client.ts构造DifyApi实例只请求本地代理路径服务端代理层web/app/api/client/dify/[appId]/查库取密钥、注入鉴权头、透传流式响应数据存储层web/db/schema/apps.ts在dify_apps表中持久化每个应用的 API Base 与 API Key请求方向示意浏览器 DifyApi 实例 │ POST /api/client/dify/{appId}/chat-messages ▼ Next.js 服务端代理getAppItem 查库 → 注入 Bearer 密钥 │ Authorization: Bearer {apiKey} ▼ Dify API {apiBase}/chat-messages代理层目录web/app/api/client/dify/[appId]/下按 Dify 官方接口一一映射了chat-messages、completion-messages、conversations、files/upload、workflows/run等全部路由前端无需感知具体端点差异。密钥入库在管理端配置 Dify 应用每个 Dify 应用的API Base与API Key都存储在数据库dify_apps表中见 db/schema/apps.ts字段为api_base与api_key。在管理端添加 Dify 应用时只需填写两项配置填写的正是上图 Dify 文档中获取的基础 URL 和密钥密钥的写入与读取都由服务端完成。web/repository/app.ts中的getAppItem函数按应用 ID 从数据库取出完整配置含密钥仅供代理路由内部使用绝不直接返回给浏览器前端无密钥调用DifyApi 封装层前端的封装类DifyApilib/dify-client.ts是理解代理层的关键。它构造请求时使用的基地址是平台自己的接口而不是 Dify 的地址const PLATFORM_API_BASE /api/client/dify const genXRequestOptions (options: IDifyApiOptions) ({ baseURL: ${PLATFORM_API_BASE}/${options.appId}, headers: { x-user-id: LocalStorageStore.get(USER_ID) }, })几个值得注意的设计无密钥请求sendMessage、uploadFile、runWorkflow等方法都只请求/api/client/dify/{appId}/...请求体中没有任何鉴权信息用户身份头通过x-user-id请求头把当前用户身份传给代理层用于 Dify 侧的会话隔离切换应用即切换代理目标updateOptions更新appId后后续请求自动指向另一个应用的代理路径。也就是说前端把Dify 调用完全抽象成了平台调用浏览器里根本不存在密钥。服务端代理注入密钥Bearer 鉴权代理以流式聊天接口web/app/api/client/dify/[appId]/chat-messages/route.ts为例代理逻辑四步走解析参数从 URL 路径取出appId查库取密钥调用getAppItem(appId)拿到该应用的apiBase和apiKey查不到返回 404注入密钥转发服务端发起fetch请求到${apiBase}/chat-messages并在请求头中拼入Authorization: Bearer ${apiKey}错误透传Dify 返回非 2xx 时原样透传状态码与错误体。const response await fetch(${app.requestConfig.apiBase}/chat-messages, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${app.requestConfig.apiKey}, }, body: JSON.stringify(data), })对于简单的 JSON 接口代理层还抽出了通用函数proxyDifyRequestlib/api-utils.ts统一负责拼 URL、注入 Bearer 头各路由只需传apiBase、apiKey和端点路径即可避免每个路由重复写鉴权逻辑。流式响应透传SSE 代理的关键实现Chat 场景下response_mode: streaming返回的是 SSE 事件流代理层必须做到边收边发否则前端要等整个响应结束才能看到首字。实现方式是新建一个ReadableStream用reader.read()循环泵送数据const stream new ReadableStream({ async start(controller) { const reader response.body?.getReader() while (true) { const { done, value } await reader.read() if (done) break controller.enqueue(value) // 收到一块立即转发一块 } controller.close() }, }) return new Response(stream, { headers: { Content-Type: text/event-stream, Cache-Control: no-cache, Connection: keep-alive, }, })同样的泵送模式也被用于 HITL 场景下重连工作流事件的workflow/[taskId]/events路由web/app/api/client/dify/[appId]/workflow/[taskId]/events/route.ts保证了工作流长任务的 SSE 事件也能实时透传。密钥如何对前端隐身敏感字段脱敏代理层除了藏住密钥还在应用管理接口上做了脱敏。lib/api-utils.ts中的createSafeApp在把应用信息返回给前端前将密钥替换为占位符export function createSafeApp(app: IDifyAppItem) { return { ...app, requestConfig: { apiBase: app.requestConfig.apiBase, apiKey: ******, // 隐藏 API Key }, } }也就是说即使是管理端查看应用详情的接口前端拿到的apiKey也永远是******。真正可用的密钥只存在于数据库和服务端内存中形成入库存储 → 服务端读取 → 请求注入 → 出参脱敏的完整闭环。方案要点总结用一张清单回顾这套 Dify API 代理层的设计✅ 密钥只存数据库dify_apps表前端代码零密钥✅ 前端DifyApi只请求平台代理路径通过x-user-id头传递用户身份✅ 服务端路由查库后注入Authorization: Bearer头转发请求✅ SSE 流式响应通过ReadableStream逐块透传首字延迟不受影响✅ 应用信息出参统一脱敏密钥永不回传浏览器✅ 通用函数proxyDifyRequest收敛鉴权逻辑新增 Dify 接口只需加一条路由。这套代理层 数据库密钥 流式透传 出参脱敏的组合正是所有需要安全调用 Dify API 而不暴露密钥的场景可直接复用的完整方案。【免费下载链接】dify-app-hub一个 Dify 应用管理平台基于 Dify API 构建提供深度优化的用户端交互界面支持 Chatflow、Workflow 等多种 Dify 应用类型适配深度思考、思维链、图表渲染、文件处理等丰富的 AI 输出形式提供开箱即用的 AI 应用解决方案。项目地址: https://gitcode.com/gh_mirrors/di/dify-app-hub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考