# 技术方案-REQ-通用-006-预生产测试通道 > **版本**: v1.0 | **日期**: 2026-08-11 | **状态**: [待评审] > **作者**: 宋献(技术) | **审核**: — > **REQ编号**: REQ-通用-006 > **关联PRD**: `../01-产品文档/00-产品规划/PRD-REQ-通用-006-预生产测试通道-v1.0.md` > **关联测试**: `../03-测试文档/03-功能测试用例/TC-REQ-通用-006-预生产测试通道.md` > **需了解的现有代码**: > - 后端: `src/backend/app/api/dev_auth.py`(Mock 登录,已存在) > - 后端: `src/backend/app/main.py`(`_is_dev_mode()` + dev 路由挂载) > - 坐席前端: `src/frontend-agent/src/views/Login.vue`、`src/frontend-agent/src/api/auth.ts`、`src/frontend-agent/src/stores/agent.ts` > - 管理前端: `src/frontend-admin/src/views/Login.vue` > - H5前端: `src/frontend-h5/src/`(登录与 token 存储) --- ## 1. 现状分析 ### 1.1 认证架构现状 - 三端统一企微扫码/OAuth(`/api/auth/qrcode` + `/api/auth/oauth2/*`),无账号密码入口 - 后端 `/api/agents/login` 已废弃(DEPRECATED),且依赖企微通讯录验证 user_id,不满足"免企微"测试诉求 - **既有测试基建**:`/api/dev/login`(`dev_auth.py`)在 `DEV_MODE=true` 时挂载,走真实 TokenService 流程、自动同步 employees 表、带角色预设(user/agent/admin/supervisor/security/多角色);本地 `src/backend/.env` 已 `DEV_MODE=true`,后端测试 conftest 亦 mock 企微 ### 1.2 前端 token 存储机制(已核实) | 端 | 存储键 | 用途 | |----|--------|------| | 坐席 | `localStorage.TOKEN_KEY`(store: agent.ts) | 请求拦截器自动附加 Bearer | | H5 | `localStorage.h5_token` | 同上 | | 管理 | 与坐席同构(login 后写入 store) | 同上 | → 测试登录仅需把 `/api/dev/login` 返回的 token 写入对应键,即可进入业务态。 --- ## 2. 总体设计 ``` 公网用户 ──► WAF ──► nginx ──┬── /itdesk|/itagent|/itadmin/ 静态页(登录页,含测试入口按钮) ├── /api/auth/* 企微扫码主登录(不变) ├── /api/dev/* ◄── nginx 闸门:allow 内网网段;deny all │ │ │ ▼ └── backend (DEV_MODE=true) ── /api/dev/login → TokenService → Redis token ``` **三层防线**: 1. **nginx 闸门**(主闸门):`location /api/dev/ { allow 内网; deny all; }` —— 公网直接 403 2. **后端二次校验**:`dev_auth.py` 各端点内部 `_dev_mode_enabled()` 再校验(`DEV_MODE=true` 才放行) 3. **前端可见性**:测试登录入口仅在内网判定(hostname 非公网域名 / 内网网段探测)时渲染 --- ## 3. 详细设计 ### 3.1 后端配置(零代码改动) 预生产 `docker-compose.yml`(`/opt/wecom-it-desk/`)backend 服务 `environment:` 追加: ```yaml - DEV_MODE=true ``` 重启后端容器(`docker compose up -d backend` 或 recreate)后: - `/api/dev/login`、`/api/dev/users`、`/api/dev/health` 挂载 - 启动日志出现 `🧪 DEV_MODE 已启用 - Mock OAuth 端点已挂载` **生产安全隔离**:新生产 compose **不得**注入 `DEV_MODE`;`.dockerignore` 已排除 `.env`(防止本地 DEV_MODE 进镜像),双保险。 ### 3.2 nginx 闸门(预生产主控) 在线上 `/opt/wecom-it-desk/nginx/nginx.conf` 生产 server 块 `location /api/` **之前**插入: ```nginx location /api/dev/ { allow 10.0.0.0/8; allow 172.16.0.0/12; allow 192.168.0.0/16; deny all; proxy_pass http://backend_api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } ``` > 注意:`location /api/dev/` 前缀比 `location /api/` 更长,nginx 最长前缀优先匹配,无需改动既有 `/api/` 块。 ### 3.3 前端三端测试登录入口 **判定内网**(复用常量,与 nginx 闸门网段同源): ```ts const TEST_NETS = ['10.', '172.16.', '172.17.', '172.18.', '172.19.', '172.20.', '172.21.', '172.22.', '172.23.', '172.24.', '172.25.', '172.26.', '172.27.', '172.28.', '172.29.', '172.30.', '172.31.', '192.168.'] function isIntranet(): boolean { // 通过 /api/dev/health 探测:内网 200 → 显示测试入口;公网 403 → 隐藏 } ``` **推荐实现**:登录页 onMounted 时静默探测 `GET /api/dev/health`: - HTTP 200 → 渲染「测试账号登录」面板(角色下拉:user/agent/admin,对应 `PRESET_DEV_USERS`) - 403/网络错误 → 不渲染(公网用户不可见) **登录动作**(坐席端示例,管理/H5 同构): ```ts const data = await apiClient.get('/dev/login', { params: { userid: 'dev-agent-001', name: '李四(IT坐席)', role: 'agent' } }) localStorage.setItem(TOKEN_KEY, data.data.token) // 与企微扫码登录写入同一键 // 刷新/跳转业务页,拦截器自动携带 token ``` > 兜底:若 `health` 探测失败(如中间层拦截),可降级为"仅 hostname 非 `itsupport.servyou.com.cn` 时显示"——测试环境通常走内网 IP/测试域名。 ### 3.4 token 生命周期 - `/api/dev/login` 返回的 token 与企微登录同源(TokenService,TTL 8h),Redis 可校验、登出接口可吊销 - 测试账号 userid 前缀 `dev-*`,与真实账号隔离,不污染统计 --- ## 4. 关键决策与取舍 | 决策点 | 选择 | 理由 | |--------|------|------| | 测试通道形态 | 启用既有 DEV_MODE + `/api/dev/*` | 零后端开发;接口已含二次校验;预设用户即测即用 | | 闸门层级 | nginx IP 白名单(主)+ 后端校验(次) | nginx 层拦截最前置、可独立回滚;后端校验防配置遗漏 | | 公网可见性 | 前端探测 `/api/dev/health` 决定是否显示测试入口 | 公网 403 → 入口自动隐藏,双保险 | | 不做的事 | 不新增生产密码登录、不改企微主流程 | 安全红线,见 PRD § 2.3 | --- ## 5. 验证方式 | # | 验证项 | 方法 | 预期 | |---|--------|------|------| | V-1 | 内网 dev/login 可用 | 内网 curl `GET /api/dev/login?userid=dev-agent-001&role=agent` | 200 + token | | V-2 | 公网 dev 接口 403 | 公网 curl `GET /api/dev/health` | 403 | | V-3 | 业务接口未误伤 | 公网 curl `GET /api/health` | 200 | | V-4 | 前端测试入口 | 内网打开三端登录页 | 显示测试账号面板,一键登录进业务页 | | V-5 | 主登录回归 | 企微扫码/OAuth 流程 | 不受影响 | | V-6 | token 真实有效 | Redis `GET user:token:*` | 存在且 TTL 正常 | --- ## 6. 风险与回滚 | 风险 | 缓解/回滚 | |------|----------| | 闸门配置语法错误 | `nginx -t` 先行校验;失败即回滚 conf(备份已建) | | 公网仍可访问 dev 接口 | 立即回滚:删除 `location /api/dev/` 块 + 移除 `DEV_MODE` → 重启后端 | | 前端构建问题 | 三端 dist 备份,回滚到上一版本 dist | | 误伤 `/api/` 业务 | 闸门仅精确前缀 `/api/dev/`,最长前缀匹配不影响其他;验证 V-3 | --- ## 7. 变更记录 | 日期 | 版本 | 变更内容 | 变更人 | 变更原因 | |------|------|----------|--------|----------| | 2026-08-11 | v1.0 | 初版 | 宋献 | 预生产测试通道技术方案 |