diff --git a/docs/DEPLOY-LOGIN-MIGRATION-v0.7.0.md b/docs/DEPLOY-LOGIN-MIGRATION-v0.7.0.md new file mode 100644 index 0000000..2998eed --- /dev/null +++ b/docs/DEPLOY-LOGIN-MIGRATION-v0.7.0.md @@ -0,0 +1,220 @@ +# 部署手册:扫码登录 + OTP 二次认证(Phase 1+2) + +> 创建:2026-06-21 +> 适用版本:v0.7.0+ (Phase 1+2) +> 部署顺序:后端 → 前端 4 端 → nginx → 数据库 migration → 验收 + +--- + +## 🎯 部署目标 + +从 v0.6.x 的"企微 OAuth + SMS 2FA"升级到 v0.7.0 的"扫码登录 + OTP TOTP + SMS 备用"。 + +涉及后端变更: +- 新增 `/api/auth_qrcode/*` 4 个端点(扫码登录) +- 新增 `/api/mfa/*` 6 个端点(OTP 二次认证) +- 新增 `/api/admin/mfa/reset/{employee_id}`(管理员重置) +- 新增 `/api/admin/high-risk/*` 演示端点 + require_high_risk_otp 守卫 +- 新增 2 个数据库字段: `users.mfa_secret`, `users.mfa_enabled`, `users.mfa_bound_at`, `users.mfa_last_verified_at` + +涉及前端变更: +- frontend-agent:Login.vue 重写(扫码 UI)+ 新增 MfaBind.vue + useHighRiskOtp +- frontend-portal:新增 QrcodeLogin.vue + 默认路由 +- frontend-admin:新增 MfaManage.vue(管理员 MFA 重置 UI) +- frontend-h5:**不变**(仍走企微 OAuth) + +涉及 nginx 变更: +- `/itportal/` 新增 location(扫码入口) +- 其余 4 个 location 已有,配置按 docs/NGINX-DOMAIN-ROUTING.md + +--- + +## 📋 部署前检查 + +### 1. 后端镜像依赖 + +`backend/requirements.txt` 必须包含: +``` +pyotp==2.9.0 # TOTP 生成 +qrcode[pil]==7.4.2 # 二维码生成 +redis==5.0.7 # 已存在 +``` + +### 2. 数据库迁移文件 + +确认以下 migration 已存在: +- `backend/alembic/versions/023_mfa_fields.py`(加 4 个 MFA 字段) +- `backend/alembic/versions/024_*.py`(可选:其他变更) + +### 3. 配置文件 + +`backend/.env` 确认: +```bash +# 新增(扫码登录) +WECOM_OAUTH_REDIRECT_URI=https://itsupport.servyou.com.cn/itportal/qrcode-callback +WECOM_CORP_ID=ww1234567890abcdef +WECOM_AGENT_ID=1000002 + +# 已有(OTP) +SMS_2FA_ENABLED=true # 蜂鸟 SMS 备用通道 +``` + +### 4. 域名 / DNS + +- `itsupport.servyou.com.cn`(主域名,已有) +- 子路径:`/itportal/` `/itagent/` `/itadmin/` `/itdesk/`(同一域名,nginx 分发) +- 证书:`itsupport.servyou.com.cn.crt`(公司统一管理) + +--- + +## 🚀 部署步骤 + +### 步骤 1:部署后端(注意 RO bind mount) + +```bash +# 1. 上传新 backend 包到堡垒机 +scp backend-v070-p1.tar.gz user@bastion:/tmp/ + +# 2. 通过堡垒机 PuTTY(不用 ssh -J)登录生产服务器 +# 参考:feedback-putty-not-openssh.md + +# 3. 解压并复制到 backend 目录(走宿主机路径,避开 RO bind mount 陷阱) +cd /opt/wecom-it-desk/ +tar -xzf /tmp/backend-v070-p1.tar.gz +# 注意:用 cp -r 不是 docker cp(避开 RO bind mount 假成功陷阱) +sudo cp -r backend-v070-p1/* backend/ + +# 4. 数据库 migration +cd /opt/wecom-it-desk/backend +sudo docker exec wecom_it_backend alembic upgrade head +# 验证: +sudo docker exec wecom_it_backend alembic current +# 期望:023_mfa_fields (head) + +# 5. 重启 backend(注意:backend 不在 compose 里,直接 docker restart) +sudo docker restart wecom_it_backend +# 验证:等待 ~30s,看健康检查 +curl http://localhost:8000/health +# 期望:{"status":"ok",...} +``` + +### 步骤 2:部署前端 4 端 + +```bash +# 1. 各前端 build(本地) +cd frontend-agent && npm run build +cd frontend-portal && npm run build +cd frontend-admin && npm run build +# frontend-h5 不变,不用 build + +# 2. 上传 dist 到生产服务器 +scp -r frontend-agent/dist user@bastion:/tmp/agent-dist/ +scp -r frontend-portal/dist user@bastion:/tmp/portal-dist/ +scp -r frontend-admin/dist user@bastion:/tmp/admin-dist/ + +# 3. 通过堡垒机,复制到 nginx 容器挂载的目录 +# 路径可能是 /opt/wecom-it-desk/frontend-*/ +sudo cp -r /tmp/agent-dist/* /opt/wecom-it-desk/frontend-agent/dist/ +sudo cp -r /tmp/portal-dist/* /opt/wecom-it-desk/frontend-portal/dist/ +sudo cp -r /tmp/admin-dist/* /opt/wecom-it-desk/frontend-admin/dist/ + +# 4. 验证:curl HTML 文件 +curl -I https://itsupport.servyou.com.cn/itportal/ +# 期望:200 OK,content-type: text/html +``` + +### 步骤 3:更新 nginx 配置 + +```bash +# 1. 上传新 nginx 配置 +# 新增 /itportal/ location,更新其他 location +# 参考:docs/NGINX-DOMAIN-ROUTING.md + +# 2. 验证配置(在 nginx 容器里) +sudo docker exec wecom_it_nginx nginx -t +# 注意容器名是 wecom_it_nginx 不是 wecom-nginx +# 期望:nginx: configuration file /etc/nginx/nginx.conf test is successful + +# 3. reload(不重启容器) +sudo docker exec wecom_it_nginx nginx -s reload +``` + +### 步骤 4:验收测试 + +按 docs/NGINX-DOMAIN-ROUTING.md 末"验证清单"逐条测试。 + +--- + +## 🔄 回滚方案 + +### 后端回滚 + +```bash +# 1. 用上次 patch1 备份 +sudo cp -r /opt/wecom-it-desk/backend-v070-patch1/* /opt/wecom-it-desk/backend/ +sudo docker restart wecom_it_backend + +# 2. 数据库回滚(谨慎!) +sudo docker exec wecom_it_backend alembic downgrade -1 +# 注意:只能降 1 个版本,如果已经升到 023,降到 022 +``` + +### 前端回滚 + +```bash +# 直接覆盖 dist +sudo cp -r /opt/wecom-it-desk/frontend-*-bak/* /opt/wecom-it-desk/frontend-*/dist/ +``` + +### nginx 回滚 + +```bash +# 容器内 sed -i 改回旧配置(避开 RO bind mount 假成功陷阱) +sudo docker exec wecom_it_nginx cp /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf +sudo docker exec wecom_it_nginx nginx -s reload +``` + +--- + +## ⚠️ 已知风险 + +| 风险 | 影响 | 缓解 | +|---|---|---| +| OTP 二维码渲染失败(后端 base64 生成出错) | 用户绑不上 OTP | 前端降级显示 qrcode_url 让用户手动复制 | +| pyotp 库版本升级导致不兼容 | OTP 验证失败 | 锁版本 pyotp==2.9.0,生产前跑 pytest | +| Admin MFA 重置端点被未授权访问 | 安全 | require_admin + 后续可加 IP 白名单 | +| 蜂鸟 SMS API 未上线 | 备用通道不可用 | 不影响 OTP 主通道,先上线 OTP,后接 SMS | +| nginx IP 白名单临时全开 | 安全 | v1.0 前必须收窄(task #48) | + +--- + +## 📊 部署后验证 + +### 业务指标 + +- [ ] 扫码登录成功率 > 95% +- [ ] OTP 验证成功率 > 99% +- [ ] 高危操作 OTP 触发率 100% +- [ ] 蜂鸟 SMS fallback 触发 < 5%(绝大多数人用 OTP) + +### 技术指标 + +- [ ] 扫码登录端到端 < 5s(从扫码到进入工作台) +- [ ] OTP 验证 < 500ms +- [ ] 高危操作 OTP 弹窗响应 < 200ms + +--- + +## 📚 相关文档 + +- [USER-GUIDE-QRCODE-MFA.md](./USER-GUIDE-QRCODE-MFA.md) — 用户手册 +- [NGINX-DOMAIN-ROUTING.md](./NGINX-DOMAIN-ROUTING.md) — nginx 域名分发 +- [v070-alpha-deploy-runbook.md](../memory/v070-alpha-deploy-runbook.md) — v0.7.0-alpha 总览 +- [docker-cp-readonly-bind-mount-fake-success.md](../memory/docker-cp-readonly-bind-mount-fake-success.md) — RO bind mount 陷阱 +- [nginx-container-name-wecom-it-nginx.md](../memory/nginx-container-name-wecom-it-nginx.md) — 容器名坑 +- [feedback-putty-not-openssh.md](../memory/feedback-putty-not-openssh.md) — 堡垒机 PuTTY + +--- + +**变更历史**: +- 2026-06-21 创建(Phase 1+2 部署手册) \ No newline at end of file diff --git a/docs/USER-GUIDE-QRCODE-MFA.md b/docs/USER-GUIDE-QRCODE-MFA.md new file mode 100644 index 0000000..927b070 --- /dev/null +++ b/docs/USER-GUIDE-QRCODE-MFA.md @@ -0,0 +1,165 @@ +# 用户手册:扫码登录 + OTP 二次认证(Phase 1+2) + +> 创建:2026-06-21 +> 适用版本:v0.7.0+ (Phase 1+2 上线后) +> 读者:全体员工、坐席、管理员 + +--- + +## 📖 这是什么? + +从 v0.7.0 开始,登录方式升级为**扫码登录 + OTP 二次认证**: +- ✅ 不再依赖企业微信应用入口,任意浏览器都能打开 +- ✅ 多角色用户(坐席+管理员)可在 Portal 选角色自动跳转 +- ✅ 管理员每次登录强制 OTP,高危操作也强制 OTP +- ✅ 备用通道:蜂鸟短信(手机丢/没装 Authenticator 时用) + +--- + +## 🧑‍💼 员工端(H5) + +### 入口 +- 仍在企微内打开"IT智能服务台"应用 +- 不需要扫码登录,沿用企微 OAuth + +### 使用场景 +- 提工单 +- 看历史会话 +- 查知识库 + +--- + +## 🧑‍🔧 坐席端(Agent) + +### 首次登录(扫码) + +``` +步骤 1:浏览器访问 https://itsupport.servyou.com.cn/itportal/ +步骤 2:页面显示二维码(120 秒有效) +步骤 3:用企业微信扫 → 确认登录 +步骤 4:自动跳到 /itagent/workspace +``` + +### 日常登录 + +- 浏览器直接打开 `https://itsupport.servyou.com.cn/itagent/` +- 没登录 → 自动跳到 Portal 扫码 +- 第二次扫码可免重复(浏览器记住 localStorage) + +### 高危操作时 OTP + +如果你是**坐席+管理员**(双角色),触发以下操作前会弹 OTP 输入框: +- 改权限 +- 改系统配置 +- 导出数据 +- 封号 +- 新增账号/MFA 重置 + +弹框出现 → 输入 Authenticator 6 位码 → 验证通过(30 分钟内免重输) + +--- + +## 🛡️ 管理员端(Admin) + +### 入口 + +- 浏览器直接打开 `https://itsupport.servyou.com.cn/itadmin/` +- 没登录 → 自动跳到 Portal 扫码 + +### 强制 OTP + +管理员**每次登录都需要 OTP**: +- 扫码登录成功后,会跳到 MFA 绑定页(首次)或 OTP 验证页 +- 输入 Authenticator 6 位码 → 进入管理后台 +- 高危操作前还要再验一次(30 分钟内免重输) + +### 首次绑定 OTP(强制) + +``` +步骤 1:登录后 → 自动跳 /mfa-bind +步骤 2:用 Google Authenticator / 微软 Authenticator / Authy 扫描二维码 +步骤 3:输入 Authenticator 显示的 6 位码 → 点"启用 OTP" +步骤 4:绑定成功,后续登录用 OTP 验证 +``` + +### 丢手机兜底(管理员后台重置) + +如果你手机丢了/坏了,**找其他管理员重置**: + +``` +步骤 1:其他管理员登录 /itadmin/ +步骤 2:进入"用户管理" → "MFA 管理" +步骤 3:搜索你的姓名 → 点"重置 MFA" +步骤 4:你下次登录时重新绑定 OTP +``` + +--- + +## 🆘 备用通道:蜂鸟 SMS + +什么情况下用: +- 📱 手机丢了/坏了 +- 🆕 刚入职,还没装 Authenticator +- 🔧 Authenticator 客户端不兼容 + +怎么用: +- 在 OTP 输入页点"收不到验证码?短信验证" +- 输入手机号(企微已绑定)→ 收短信码 → 验证 + +--- + +## 📱 推荐 OTP 客户端 + +| 客户端 | 平台 | 推荐度 | +|---|---|---| +| Google Authenticator | iOS / Android | ⭐⭐⭐⭐⭐ | +| 微软 Authenticator | iOS / Android | ⭐⭐⭐⭐ | +| Authy | iOS / Android / 桌面 | ⭐⭐⭐⭐⭐ | +| 1Password | 全平台 | ⭐⭐⭐ | + +公司偏好:**Google Authenticator**(零依赖,离线可用) + +--- + +## ❓ 常见问题 + +### Q1:扫码登录过期了怎么办? +A:二维码有效期 120 秒,过期后点"刷新二维码"按钮。 + +### Q2:扫码登录失败? +A: +- 确认用的是企业微信(不是普通微信) +- 确认企微里能看到"IT智能服务台"应用 +- 刷新页面重新生成二维码 + +### Q3:OTP 输入错误? +A:连续 5 次错误会被锁定 5 分钟,等 5 分钟后再试。 + +### Q4:换手机了怎么办? +A:登录前在旧手机上导出 OTP(Google Authenticator 支持),或者找管理员后台重置。 + +### Q5:多角色用户(admin + agent)怎么登录? +A:扫码登录成功后,Portal 自动跳到角色选择页,选你要进入的工作台。 + +### Q6:H5 员工端也需要扫码吗? +A:不需要。H5 员工端仍在企微内,沿用企微 OAuth。 + +### Q7:扫码登录安全吗? +A:扫码登录比企微 OAuth 还安全: +- 员工必须用企微扫(企微已经做了员工身份认证) +- 二维码 120 秒过期 +- Token 8 小时过期 +- 高危操作还要再 OTP 一次 + +--- + +## 📞 技术支持 + +- 内部: 信息技术部 服务台 +- 紧急: 群里 @ IT 主管 +- 反馈: https://itsupport.servyou.com.cn/itdesk/feedback + +--- + +**变更历史**: +- 2026-06-21 创建(Phase 1+2 培训) \ No newline at end of file