- 后端 API(Flask + Gunicorn) - RAG 引擎(混合检索 + 云端 Reranker + 引用溯源) - 文档解析(MinerU + 多格式支持) - Docker 生产部署配置 - 排除前端项目、敏感配置、模型文件
11 KiB
11 KiB
认证与权限配置指南
文档类型: 配置指南 创建日期: 2026-04-12 最后更新: 2026-04-13 状态: 已实施
一、概述
API 服务采用网关注入认证模式,从 HTTP Header 中读取用户信息,不处理本地登录认证。
1.1 认证流程
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 前端 │────▶│ 网关 │────▶│ 后端 API │────▶│ Dify │
│ (JWT Token) │ │ (验证注入) │ │ (Header认证) │ │ (Token认证) │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │ │ │
│ Authorization: │ X-User-ID: xxx │ │
│ Bearer <token> │ X-User-Role: xxx │ user_token: xxx │
└──────────────────▶└──────────────────▶└──────────────────▶│
│ │
│ Authorization: Bearer {{user_token}}
二、网关配置
2.1 需要注入的 Header
| Header 名称 | 必需 | 说明 | 示例 |
|---|---|---|---|
| X-User-ID | 是 | 用户唯一标识 | user001 |
| X-User-Name | 否 | 用户名 | 张三 |
| X-User-Role | 否 | 用户角色 | admin/manager/user |
| X-User-Department | 否 | 部门 | 技术部 |
2.2 前端配置
- 用户登录后获取 JWT token
- 请求时在
AuthorizationHeader 中携带 token:Bearer <token>
2.3 后端配置
- 网关验证 token 后注入用户信息 Header
- 后端 API 通过
request.headers.get('X-User-ID')获取用户信息
三、角色权限
3.1 角色映射
后端角色会自动映射到本地角色:
| 后端角色 | 本地角色 |
|---|---|
| administrator | admin |
| admin | admin |
| manager | manager |
| user | user |
| normal | user |
| guest | user |
如需添加新的角色映射,请修改 auth/gateway.py 中的 ROLE_MAPPING 字典。
3.2 权限级别
| 角色 | 可访问的安全级别 | 向量库读取 | 向量库写入 | 向量库删除 | 同步 |
|---|---|---|---|---|---|
| admin | public, internal, confidential | 所有 | 所有 | 所有 | 所有 |
| manager | public, internal, confidential | public + 本部门 | 本部门 | 本部门 | 本部门 |
| user | public, internal | public + 本部门 | ❌ | ❌ | ❌ |
四、开发测试
4.1 启用开发模式
# Windows
set DEV_MODE=true
# Linux/Mac
export DEV_MODE=true
4.2 模拟用户测试
开发模式下,可以:
- 不传 Header 会自动使用默认测试用户(admin/开发部)
- 使用
Authorization: Bearer mock-token-<username>模拟登录
测试账号:
| 用户名 | 密码 | 角色 | 部门 |
|---|---|---|---|
| admin | admin123 | admin | 管理部 |
| testuser | test123 | user | 技术部 |
| manager | manager123 | manager | 财务部 |
4.3 使用 Header 模拟用户
# 测试普通用户
curl -H "X-User-ID: test001" -H "X-User-Name: 测试用户" -H "X-User-Role: user" \
http://localhost:5001/auth/me
# 测试管理员
curl -H "X-User-ID: admin001" -H "X-User-Name: 管理员" -H "X-User-Role: admin" \
http://localhost:5001/stats
# 使用 mock token
curl -H "Authorization: Bearer mock-token-admin" \
http://localhost:5001/auth/me
五、API 接口分类
5.1 公开接口(无需认证)
| 接口 | 方法 | 说明 |
|---|---|---|
/health |
GET | 健康检查 |
5.2 需要认证的接口
所有其他接口都需要通过网关访问,网关会注入用户信息。
5.3 管理员专用接口
以下接口需要 admin 角色:
| 接口 | 方法 | 说明 |
|---|---|---|
/stats |
GET | 系统统计 |
/sync |
POST | 手动触发同步 |
/sync/start |
POST | 启动文件监控 |
/sync/stop |
POST | 停止文件监控 |
/graph/build |
POST | 重建知识图谱 |
/audit/logs |
GET | 审计日志 |
/collections |
POST | 创建向量库 |
/collections/<name> |
DELETE | 删除向量库 |
/faq |
POST | 新增 FAQ |
/faq/<id> |
PUT/DELETE | 更新/删除 FAQ |
/exam/<id>/review |
POST | 审核试卷 |
5.4 保留的接口
| 接口 | 方法 | 说明 |
|---|---|---|
/auth/me |
GET | 获取当前用户信息(从 Header 读取) |
5.5 已移除的接口
以下接口已移除(由后端网关处理):
POST /auth/login- 用户登录POST /auth/register- 用户注册POST /auth/change-password- 修改密码GET /auth/users- 用户列表PUT /auth/users/<user_id>- 更新用户DELETE /auth/users/<user_id>- 删除用户
六、错误响应
6.1 401 未认证
{
"error": "缺少用户信息",
"message": "请通过网关访问,或设置 DEV_MODE=true 进行开发测试"
}
6.2 403 权限不足
{
"error": "权限不足",
"message": "此接口需要以下角色之一: admin",
"your_role": "user"
}
七、对接清单
7.1 Dify 工作流修改
当前状态:使用变量传入用户信息
variables:
- variable: user_id
default: 'exam-system'
- variable: user_role
default: 'admin'
- variable: user_department
default: ''
headers: 'Content-Type:application/json
X-User-ID:{{#1774596726631.user_id#}}
X-User-Role:{{#1774596726631.user_role#}}
X-User-Department:{{#1774596726631.user_department#}}'
对接后修改:改用 Bearer token 认证
variables:
- variable: user_token
label: 用户Token
hint: 'JWT认证token,由网关注入'
default: ''
required: true
type: text-input
headers: 'Content-Type:application/json
Authorization:Bearer {{#1774596726631.user_token#}}'
操作步骤:
- 移除
user_id、user_role、user_department变量 - 添加
user_token变量 - 修改 HTTP 请求的 headers,使用
Authorization: Bearer <token>
7.2 Python 后端修改
exam_pkg/manager.py 当前状态:
def generate_exam_by_file(
file_path: str,
collection: str,
user_id: str = None,
user_role: str = None,
user_department: str = None,
...
) -> dict:
inputs = {
"file_path": file_path,
"collection": collection,
"user_id": user_id or "exam-system",
"user_role": user_role or "admin",
"user_department": user_department or "",
...
}
对接后修改:
def generate_exam_by_file(
file_path: str,
collection: str,
user_token: str = None, # 改为接收 token
...
) -> dict:
inputs = {
"file_path": file_path,
"collection": collection,
"user_token": user_token or "", # 传入 token
...
}
exam_pkg/api.py 当前状态:
result = generate_exam_by_file(
file_path=file_path,
collection=collection,
user_id=user.get('user_id'),
user_role=user.get('role'),
user_department=user.get('department'),
...
)
对接后修改:
# 从请求头获取 Authorization token
auth_header = request.headers.get('Authorization', '')
user_token = auth_header.replace('Bearer ', '') if auth_header.startswith('Bearer ') else ''
result = generate_exam_by_file(
file_path=file_path,
collection=collection,
user_token=user_token, # 传递 token
...
)
7.3 auth/gateway.py
当前状态:已支持网关注入 Header 认证,无需修改
def require_gateway_auth(f):
# 从 Header 读取用户信息
user_id = request.headers.get('X-User-ID')
username = request.headers.get('X-User-Name', '')
role = request.headers.get('X-User-Role', '')
department = request.headers.get('X-User-Department', '')
# 必须有用户 ID
if not user_id:
return jsonify({"error": "缺少用户信息"}), 401
# 将用户信息附加到 request 对象
request.current_user = {...}
八、测试验证
8.1 网关认证测试
# 测试网关注入 Header
curl -X POST http://localhost:5001/search \
-H "Content-Type: application/json" \
-H "X-User-ID: test_user" \
-H "X-User-Role: admin" \
-H "X-User-Department: finance" \
-d '{"query": "测试", "top_k": 3}'
预期结果:返回搜索结果,无认证错误
8.2 出题功能测试
# 测试出题接口(携带网关注入的 Header)
curl -X POST http://localhost:5001/exam/generate-by-file \
-H "Content-Type: application/json" \
-H "X-User-ID: test_user" \
-H "X-User-Role: admin" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-d '{
"file_path": "public/公司简介.txt",
"collection": "public_kb",
"choice_count": 2
}'
预期结果:成功生成题目 JSON
8.3 权限控制测试
| 用户角色 | 可访问向量库 | 预期结果 |
|---|---|---|
| admin | 所有向量库 | ✅ 成功 |
| manager (finance) | public_kb + dept_finance | ✅ 本部门成功,其他部门拒绝 |
| user (hr) | public_kb + dept_hr(只读) | ✅ 只读成功,写入拒绝 |
九、回滚方案
如果对接后出现问题,可以快速回滚到模拟测试模式:
9.1 设置环境变量
# Windows
set DEV_MODE=true
# Linux/Mac
export DEV_MODE=true
9.2 恢复工作流
使用 Git 恢复工作流文件:
git checkout tests/自动出题(带溯源).yml
git checkout tests/自动批卷\(带溯源\)\ .yml
十、文件变更记录
| 文件 | 变更 |
|---|---|
| auth/gateway.py | 新增,网关认证模块 |
| api/auth_routes.py | 移除登录路由,使用网关认证 |
| exam_pkg/api.py | 更新认证装饰器 |
十一、注意事项
- 角色映射:如果后端的角色名称与本地不同,需要修改
auth/gateway.py中的ROLE_MAPPING - 开发模式:生产环境请确保不设置
DEV_MODE=true - 前端:前端由其他团队负责,需要他们确保请求经过网关
- 安全性:敏感操作需要 admin 角色,确保权限控制正确
十二、变更记录
| 日期 | 版本 | 变更内容 |
|---|---|---|
| 2026-04-13 | 2.0 | 合并登录功能对接清单和网关认证对接说明 |
| 2026-04-12 | 1.0 | 创建认证对接文档 |