# 认证与权限配置指南 > **文档类型**: 配置指南 > **创建日期**: 2026-04-12 > **最后更新**: 2026-06-04 > **状态**: 已实施 --- ## 一、概述 API 服务采用网关注入认证模式,从 HTTP Header 中读取用户信息,不处理本地登录认证。 ### 1.1 认证流程 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 前端 │────▶│ 网关 │────▶│ 后端 API │────▶│ Dify │ │ (JWT Token) │ │ (验证注入) │ │ (Header认证) │ │ (Token认证) │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ │ Authorization: │ X-User-ID: xxx │ │ │ Bearer │ 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 - 请求时在 `Authorization` Header 中携带 token:`Bearer ` ### 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 启用开发模式 ```bash # Windows set DEV_MODE=true # Linux/Mac export DEV_MODE=true ``` ### 4.2 模拟用户测试 开发模式下,可以: 1. 不传 Header 会自动使用默认测试用户(admin/开发部) 2. 使用 `Authorization: Bearer mock-token-` 模拟登录 **测试账号**: | 用户名 | 密码 | 角色 | 部门 | |--------|------|------|------| | admin | admin123 | admin | 管理部 | | testuser | test123 | user | 技术部 | | manager | manager123 | manager | 财务部 | ### 4.3 使用 Header 模拟用户 ```bash # 测试普通用户 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 | 停止文件监控 | | `/collections` | POST | 创建向量库 | | `/collections/` | DELETE | 删除向量库 | | `/faq` | POST | 新增 FAQ | | `/faq/` | PUT/DELETE | 更新/删除 FAQ | | `/exam//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/` - 更新用户 - `DELETE /auth/users/` - 删除用户 --- ## 六、错误响应 ### 6.1 401 未认证 ```json { "error": "缺少用户信息", "message": "请通过网关访问,或设置 DEV_MODE=true 进行开发测试" } ``` ### 6.2 403 权限不足 ```json { "error": "权限不足", "message": "此接口需要以下角色之一: admin", "your_role": "user" } ``` --- ## 七、对接清单 ### 7.1 Dify 工作流修改 **当前状态**:使用变量传入用户信息 ```yaml 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 认证 ```yaml 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#}}' ``` **操作步骤**: 1. 移除 `user_id`、`user_role`、`user_department` 变量 2. 添加 `user_token` 变量 3. 修改 HTTP 请求的 headers,使用 `Authorization: Bearer ` ### 7.2 Python 后端修改 **exam_pkg/generator.py 当前状态**: ```python 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 "", ... } ``` **对接后修改**: ```python 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 当前状态**: ```python 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'), ... ) ``` **对接后修改**: ```python # 从请求头获取 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 认证,**无需修改** ```python 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 网关认证测试 ```bash # 测试网关注入 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 出题功能测试 ```bash # 测试出题接口(携带网关注入的 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 " \ -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 设置环境变量 ```bash # Windows set DEV_MODE=true # Linux/Mac export DEV_MODE=true ``` ### 9.2 恢复工作流 使用 Git 恢复工作流文件: ```bash git checkout tests/自动出题(带溯源).yml git checkout tests/自动批卷\(带溯源\)\ .yml ``` --- ## 十、文件变更记录 | 文件 | 变更 | |------|------| | auth/gateway.py | 新增,网关认证模块 | | exam_pkg/api.py | 更新认证装饰器 | --- ## 十一、注意事项 1. **角色映射**:如果后端的角色名称与本地不同,需要修改 `auth/gateway.py` 中的 `ROLE_MAPPING` 2. **开发模式**:生产环境请确保不设置 `DEV_MODE=true` 3. **前端**:前端由其他团队负责,需要他们确保请求经过网关 4. **安全性**:敏感操作需要 admin 角色,确保权限控制正确 --- ## 十二、变更记录 | 日期 | 版本 | 变更内容 | |------|------|---------| | 2026-06-04 | 2.1 | 移除已废弃的 Graph RAG 端点(/graph/build)和审计端点(/audit/logs);移除 api/auth_routes.py 引用;代码示例更新为 generator.py | | 2026-04-13 | 2.0 | 合并登录功能对接清单和网关认证对接说明 | | 2026-04-12 | 1.0 | 创建认证对接文档 |