1. 方案背景与目标
背景:本项目采用 Dify 作为 LLM 能力后端(BaaS),前端通过调用 API 获取 AI 响应。
目标:
-
用户隔离:确保不同用户的数据(上下文、记忆、变量)严格隔离,互不可见。
-
安全性:防止恶意用户伪造身份获取他人对话记录。
-
隐私保护:避免将用户的敏感真实身份信息(如手机号、明文 ID)直接暴露给 Dify 端。
2. 总体架构设计
采用 Backend-For-Frontend (BFF) / 代理模式。
严禁前端直接调用 Dify API。所有的请求必须经过业务后端(Business Backend)进行鉴权和参数注入。
2.1 交互时序图
Code snippet
sequenceDiagram
participant User as 客户端 (App/Web)
participant Backend as 业务后端 (Your Server)
participant Dify as Dify API Service
User->>Backend: 1. 发起对话请求 (携带 Token, Query)
Note right of User: Header: Authorization: Bearer <token>
Backend->>Backend: 2. 鉴权 (Validate Token)
Backend->>Backend: 3. 解析 UserID (e.g., 10086)
Backend->>Backend: 4. 生成 Dify User 标识 (Hash/UUID)
Backend->>Dify: 5. 调用 /chat-messages
Note right of Backend: Body: { query: "...", user: "hashed_10086" }
Dify-->>Backend: 6. 返回流式/阻塞响应
Backend-->>User: 7. 转发响应给客户端
3. 详细实现逻辑
3.1 核心字段定义
在调用 Dify API 时,需重点关注以下两个字段的生命周期管理:
| 字段名 | 来源 | 作用 | 管理策略 |
|---|---|---|---|
user |
业务后端生成 | 用户隔离的唯一凭证。Dify 依此区分上下文归属。 | 强制覆盖 。由后端根据 Token 解析出的用户 ID 映射生成,禁止前端直接传递此参数。 |
conversation_id |
Dify 返回 | 会话隔离凭证。区分同一个用户下的不同聊天窗口。 | 前端维护。前端存储在本地,发起请求时透传给后端,后端透传给 Dify。 |
3.2 用户标识映射策略 (User Identity Mapping)
为了保护隐私,建议不要直接使用数据库的主键 ID(如 1)或业务账号(如 admin),建议使用 Hash 加盐 或 UUID 映射。
-
方案 A (推荐 - Hash映射):
-
dify_user_id = HMAC_SHA256(uid, secret_salt) -
优点:确定性(同一个用户永远生成相同的 ID),方便后续统计 Token 用量,且不可逆(Dify 侧无法反推真实身份)。
-
-
方案 B (简单 - 直接映射):
-
dify_user_id = "user_" + uid -
优点:调试方便,直观。
-
3.3 接口开发规范
A. 客户端 -> 业务后端 (Request)
前端只需关注业务逻辑,无需关心 Dify 的底层实现。
HTTP
POST /api/ai/chat
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"query": "帮我写一个Python脚本",
"conversation_id": "53006d08-...", // 如果是新会话,传 null 或空字符串
"file_url": "..." // (可选) 图片/文件上传逻辑
}
B. 业务后端 -> Dify API (Proxy Request)
后端负责"注入"身份信息。
HTTP
POST https://api.dify.ai/v1/chat-messages
Authorization: Bearer <DIFY_APP_KEY>
Content-Type: application/json
{
"inputs": {},
"query": "帮我写一个Python脚本", // 来自前端
"response_mode": "streaming",
"conversation_id": "53006d08-...", // 来自前端透传
"user": "hmac_u8832_x992", // 【关键】由后端计算并强制注入,不可被前端参数覆盖
"files": []
}
4. 会话管理逻辑 (Session Handling)
4.1 开启新会话 (New Chat)
-
前端动作:用户点击"新建聊天"。
-
前端请求 :调用接口时,
conversation_id设为null。 -
Dify 行为 :识别到空 ID,创建一个新会话,并在响应中返回新的
conversation_id。 -
前端处理 :接收到响应中的
conversation_id,更新本地状态(URL 参数或 State)。
4.2 历史记录回溯 (History)
如果需要在前端展示历史对话列表:
-
Dify 接口 :调用
GET /conversations。 -
后端中转 :同样需要后端代理,并在 URL 参数中附加
user=hmac_u8832_x992。 -
隔离效果 :Dify 只会返回该
user标识下的历史会话列表。
5. 安全与异常处理
5.1 身份防伪造 (Anti-Spoofing)
-
风险点 :如果后端直接盲目透传前端的所有参数,黑客可能在前端构造
{ "user": "admin_id" }请求。 -
防御 :在构造发往 Dify 的 Request Body 时,代码必须显式重写
user字段。Python
# Python 伪代码示例 payload = request.json # 强制覆盖,无视前端传来的 user payload['user'] = get_current_user_id_hash(request.user) response = requests.post(dify_url, json=payload)
5.2 敏感数据过滤
-
Dify 的日志中会记录
query和response。 -
建议在发送给 Dify 前,如果业务对隐私极其敏感,可在后端增加一层 PII (个人身份信息) 过滤逻辑,将手机号、身份证等正则替换为
[REDACTED]。
6. 实施 Checklist
-
\] **后端**:已实现 Token 鉴权中间件。
-
\] **后端** :`user` 字段采用了 Hash 或加密 ID,未传输明文手机号。
-
\] **运维**:Dify API Key 已存储在后端环境变量中,未暴露在前端代码。