文件
hyb-oa/.trellis/tasks/07-30-pc-wecom-qr-login/prd.md
T
wangsli fb164eb690
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s
增加 PC 企业微信扫码登录(07-30-pc-wecom-qr-login)
2026-07-30 17:16:22 +08:00

7.4 KiB

PC 企业微信扫码登录

Goal

让已经完成 OA 与企业微信 userid 映射的员工,在普通 PC 浏览器访问 OA 登录页时,可以使用企业微信完成扫码或桌面端快速登录,不必输入 OA 密码或邮箱验证码;同时保留现有企业微信工作台免登链路。

Scope

  • 普通 PC 浏览器登录页的企微托管 Web 登录入口。
  • 服务端企微 Web 登录 URL、入口来源、短期浏览器关联 cookie、共享 callback 和登录审计。
  • 默认关闭的独立生产开关、配置/readiness 合同、回滚和真实扫码验收。
  • 现有工作台免登、绑定、onboard、密码和邮箱验证码登录的回归保护。

Background and Confirmed Facts

  • 当前普通浏览器登录页只提供账号密码和企业邮箱验证码;企业微信入口文案要求用户从企微工作台打开 OA。
  • 当前后端已具备 code -> userid -> OA 绑定/唯一自动映射 -> 会话签发 全链路,并已覆盖未映射、映射冲突、账号停用和成功登录。
  • 当前移动/工作台入口使用企业微信“网页授权登录”;PC 普通浏览器应使用企业微信“Web 登录”入口,二者不是同一个授权地址。
  • 企业微信官方文档《Web登录组件》(2026-01-14)支持两种网站接入:使用 @wecom/jssdk >= 2.3.2 内嵌登录组件,或构造企微托管 Web 登录链接。
  • 自建应用 Web 登录使用 login_type=CorpApp、企业 CorpID、应用 AgentID、回调地址和 state;成功后回调携带 code 与原样 state。
  • 企业微信官方文档《获取用户登录身份》(2026-04-29)确认 Web 登录 code 仍由 /cgi-bin/auth/getuserinfo 消费,code 只能使用一次,5 分钟未使用自动过期;现有后端兑换接口可复用。
  • 首版采用点击按钮后跳转企业微信托管 Web 登录页,不在 OA 登录页内嵌企微 JS-SDK 或第三方脚本。这样不扩大密码与邮箱验证码页面的脚本信任边界,并让企微 CDN 或组件异常不影响 OA 既有登录表单。
  • 现有 state 是 HMAC 签名的短期 payload,不是 JWT;它包含过期时间和随机 nonce,但 nonce 当前没有持久化消费,实施时必须验证扫码入口的 CSRF 与重放边界,不能仅凭 nonce 字段宣称一次性防重放。
  • 当前 mode 表示 login / bind / onboard 业务流程。PC 扫码入口不得引入 mode=qr;入口来源应使用独立、固定白名单字段,例如 entrySource=pc_qr | wecom_workbench。

Requirements

R1 普通 PC 浏览器入口

  • 普通 PC 浏览器登录页展示清晰的“企业微信扫码登录”入口。
  • 点击入口后跳转企业微信托管 Web 登录页;OA 登录页不加载 @wecom/jssdk、企微 CDN 脚本或内嵌二维码 iframe。
  • 入口不得取代账号密码和邮箱验证码等应急方式。
  • 企业微信内置 WebView 继续使用当前工作台一键进入,不重复展示 PC 扫码入口。

R2 复用既有身份与会话链路

  • Web 登录成功后的 code 复用现有 userid 获取、OA 绑定查找、唯一自动映射、会话签发、设备指纹和安全回跳逻辑。
  • 已绑定且 active 的员工可直接登录;不要求先用 OA 用户名密码完成首次绑定。
  • 未映射、映射冲突、OA/企微账号停用时继续失败关闭,并显示现有可理解提示。
  • 不改变 bind 和 onboard 两条业务流程。

R3 入口来源与审计

  • mode 保持业务语义,不承担入口区分。
  • entrySource 只接受服务端固定白名单值,未知值不得进入审计或影响授权地址选择。
  • 成功登录审计记录入口来源和既有 binding source,但不记录 code、state、userid、Secret 或原始企微响应。

R4 安全边界

  • state 必须服务端签名、短时有效、校验回调来源上下文,并继续限制 returnTo,防止开放重定向。
  • PC 扫码请求必须通过短期 HttpOnly、SameSite=Lax 同站关联 cookie 将随机 nonce 与发起浏览器绑定;回调校验后立即清除该 cookie,正常浏览器重复回调在 OA 侧失败关闭,不新增数据库 nonce 表。若恶意客户端同时重放回调 URL 与旧 cookie,则由企微一次性 code 阻止第二次兑换和会话创建。
  • 实施前通过测试明确验证 state 篡改、过期、入口来源伪造、code 缺失、企微拒绝授权和重复回调行为。
  • 前端不得接触应用 Secret;Web 登录 URL 由服务端按受控配置构造。

R5 配置、上线与回滚

  • 生产启用前只读核对现有自建应用是否已开启“企业微信授权登录”,以及 OA 域名是否满足 OAuth 可信域名或 Web 网页授权回调域名要求。
  • 若需要修改企微后台、生产环境变量、部署或真实扫码验收,必须另行获得明确批准。
  • 功能应具备独立开关或可安全退回现有登录页的配置边界;回滚不得影响工作台免登、密码登录和邮箱验证码登录。

Acceptance Criteria

  • 普通 PC 浏览器登录页出现明确的企业微信 Web 登录入口,企业微信内置 WebView 仍走原工作台入口。
  • 已映射 active 员工使用手机企微扫码后进入原请求的安全 OA 页面,无需 OA 密码或首次绑定。
  • 已登录企微桌面端时,可按企微官方组件能力完成快速登录或扫码登录。
  • 未映射、冲突、OA 停用和企微停用账号均失败关闭,页面提示不引导用户先用密码绑定。
  • 登录成功审计可区分 pc_qr 与 wecom_workbench,且不含 code、state、Secret、完整 userid 或原始 payload。
  • state 篡改、过期、非法入口来源、缺 code、重复使用 code 和恶意 returnTo 的自动化负例通过。
  • PC 扫码回调缺少、篡改或不匹配浏览器关联 cookie 时失败关闭且不调用企微 code 兑换接口;正常浏览器回调后 cookie 被清除,企微一次性 code 回归证明不会创建第二个会话。
  • 现有工作台登录、绑定、onboard、账号密码和邮箱验证码回归通过。
  • 本地后端/前端门禁通过;获得部署批准后,生产配置核验、公网构建标识、真实 PC 扫码和回滚检查通过,之后才通知用户可测试。

Test Plan

  • 后端单元测试覆盖 PC 配置和托管 URL、entrySource 白名单、state 和浏览器关联 cookie、安全回跳、成功/失败映射、审计脱敏及现有工作台/bind/onboard 回归。
  • 前端测试与构建覆盖普通浏览器按钮、企微 WebView 入口隔离、配置关闭时降级,以及 returnTo/设备指纹传递。
  • 执行 Prisma validate、前后端 typecheck/build、流程合同、文档审计、Trellis governance、task validate 和 git diff --check。
  • 生产阶段另行批准后执行企微后台配置核验、公网 readiness/构建标识、现有登录回归、真实 PC 扫码、审计抽查和关闭开关回滚验证。

Out of Scope

  • 不建设新的 OA 账号体系,不要求逐人设置或分发初始密码。
  • 不改变企微通讯录、userid 与 OA 账户的既有映射规则。
  • 不扩展到微信个人号、第三方企业、外部联系人或多租户 SSO。
  • 不在本任务重做找回密码、邮箱验证码或企业微信工作台页面体验。
  • 不把 PC 扫码入口复用于绑定或新员工 onboard,除非后续任务单独批准。
  • 不引入企微 JS-SDK、站内二维码 iframe,也不在本任务开启全站 CSP 改造;CSP 基线另行治理。