Dify 的「Button」组件本质是前端触发的 POST 请求(非表单提交),其 payload 是标准 JSON,但结构深度嵌套:{“message”: {“user_input”: “xxx”, “conversation_id”: “conv_xxx”, “user_id”: “usr_yyy”}}。而 n8n 默认 Webhook 节点仅接收原始 body,不自动展开 message 层;且 Dify 不在请求头中透传 X-Dify-Signature(需在 Dify 后端自定义中间件显式注入),导致 n8n 无法做 HMAC 校验。这是所有集成失败的起点。
- ✅ 推荐路径(JSON Body + Header 透传):修改 Dify Chat UI 源码,在按钮点击时通过
fetch手动构造请求,显式携带Content-Type: application/json和X-Dify-Session-ID等自定义头; - ⚠️ 折中路径(Base64 编码 body):将完整
message对象序列化后 Base64 编码为 URL query 参数(如?payload=eyJtZXNzYWdlIjp7InVzZXJfaW5wdXQiOiJ...}),规避中文乱码与长度限制; - ❌ 反模式(明文 query string):直接拼接
?input=你好&uid=123—— UTF-8 编码未 encodeURIComponent 时必乱码,且 URL 长度超 2048 字符即被截断。
在 n8n Webhook 节点后接入「Function Item」节点,使用如下 JavaScript 安全解析:
const body = $input.all()[0].json; // 防御性解构,兼容空值/缺失字段 const message = body.message || {}; const user_input = message.user_input?.trim() || ''; const conversation_id = message.conversation_id || 'unknown'; const user_id = message.user_id || 'anonymous'; return [ { json: { user_input, conversation_id, user_id, timestamp: new Date().toISOString(), request_id: crypto.randomUUID() // 用于幂等性 } } ];
Dify 使用 SHA256-HMAC 签名,密钥为 DIFY_API_KEY(需在 n8n 设置为环境变量)。校验逻辑需在 Function 节点中前置执行:
步骤 操作 1 从
graph LR A[收到请求] --> B{查 Redis} B -- 存在 key? --> C[返回缓存结果] B -- 不存在 --> D[生成幂等 Key
req.headers['x-dify-signature'] 提取签名(若 Dify 已透传) 2 对原始
req.body(Buffer)计算
HMAC-SHA256,密钥为
process.env.DIFY_API_KEY 3 使用
crypto.timingSafeEqual() 比较签名,防时序攻击
conv_id + user_id + action_type + 24h_ttl] D --> E[SETNX + EX 86400] E -- success --> F[执行主逻辑] E -- fail --> C F --> G[写入结果到 Redis]
n8n 最终必须通过「HTTP Response」节点返回:
- Status Code:
200 OK - Headers:
Content-Type: application/json; charset=utf-8 - Body:
{"type": "text", "content": "✅ 已处理:用户输入「xxx」"}或{"type": "url", "url": "https://example.com/report?id=xxx"}
任何偏离该格式(如返回 HTML、空 body、非 200 状态码)都将导致 Dify 前端按钮无限 loading 或静默失败。
在 n8n 工作流中插入「Debug」节点并启用「Log Output」,记录以下字段:
- 原始请求头(过滤敏感字段)
- 解析后的 conversation_id / user_id
- 签名校验结果(true/false)
- 幂等 Key 计算过程
- Redis 写入状态
- 最终响应体 JSON 字符串
- 耗时(ms)—— 超过 3s 触发告警
- 错误堆栈(捕获 try/catch)
- Webhook URL 必须启用 HTTPS,禁用 HTTP(Dify 前端会拦截)
- n8n 实例需配置反向代理(如 Nginx)添加
proxy_set_header X-Real-IP $remote_addr;支持 IP 限流 - 为 Webhook 路径设置独立 Basic Auth(如
/webhook/dify-button?auth=xxx),避免暴露于公网扫描 - 所有敏感密钥(DIFY_API_KEY、Redis 密码)均通过 n8n
Settings > Environment Variables注入,禁止硬编码
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/267352.html