Files
wecom_it_smart_desk/docs/04-运维文档/部署运维/07-扫码登录OTP部署指南-v0.7.0.md
T
Simon facc04aa65 chore: docs 结构整改 + compose 双目录对齐(合并重建提交)
本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交
(5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。

一、docs 结构整改(整改 #14)
根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入,
随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录
树并存于 docs/,共 791 文件、双分类体系冲突。

修复动作:
- b2 同名异主题文件改名迁移保全 9 个
- C 类 39 个孤立文件按主题正确归类
- A/B1 类 222 个重复文件删除(新结构已有内容副本)
- 9 个旧独有空目录删除
- 270 处内部引用按 verified 映射改写
- 整改记录 #14 登记于 04-运维文档/部署运维

结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。
残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。

二、compose 双目录对齐(消除踩坑 A)
- docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist
  改为 src/frontend-*/dist(h5 / agent / admin / terminal)
- docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/
- 效果:本地 docker compose up 不再把根目录 stale dist 挂回,
  与线上一致,分叉隐患消除(已 docker compose config 校验通过)

防复发铁律:
- 重构须提交;仓库修复须 git stash -u 或先 commit
- 新结构须 git add 并提交,避免再次 untracked 复活
- H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
2026-08-07 22:31:32 +08:00

7.5 KiB
Raw Blame History

部署手册:扫码登录 + OTP 二次认证(Phase 1+2)

创建:2026-06-21 适用版本:v0.7.0+ (Phase 1+2) 部署顺序:后端 → 前端 4 端 → nginx → 数据库 migration → 验收

⚠️ 端点命名修正(2026-08-05:本文档原始使用 /api/mfa/*/api/admin/mfa/reset/{employee_id},该命名为 AUTH-03 三端认证重构前的规划命名。当前生产实现已统一为 /api/auth/otp-*(含 /api/auth/otp-admin-reset/{employee_id}),详见 06-OTP二次验证实现.md 与技术方案。下方正文已同步修正。


🎯 部署目标

从 v0.6.x 的"企微 OAuth + SMS 2FA"升级到 v0.7.0 的"扫码登录 + OTP TOTP + SMS 备用"。

涉及后端变更:

  • 新增 /api/auth_qrcode/* 4 个端点(扫码登录)
  • 新增 /api/auth/otp-* 6 个端点(OTP 二次认证)
  • 新增 /api/auth/otp-admin-reset/{employee_id}(管理员重置)
  • 新增 /api/admin/high-risk/* 演示端点 + require_high_risk_otp 守卫
  • 新增 4 个数据库字段: 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 确认:

# 新增(扫码登录)
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)

# 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 端

# 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 配置

# 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 末"验证清单"逐条测试。


🔄 回滚方案

后端回滚

# 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

前端回滚

# 直接覆盖 dist
sudo cp -r /opt/wecom-it-desk/frontend-*-bak/* /opt/wecom-it-desk/frontend-*/dist/

nginx 回滚

# 容器内 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

📚 相关文档


变更历史:

  • 2026-06-21 创建(Phase 1+2 部署手册)
  • 2026-08-05 端点命名修正:/api/mfa/*/api/auth/otp-*/api/admin/mfa/reset/{employee_id}/api/auth/otp-admin-reset/{employee_id}(AUTH-03 重构后的真实实现);数据库字段描述由"2 个"更正为"4 个"