华为云登录排障实录:为什么二维码和验证码总在“最后一步”失效

举报
yd_296261293 发表于 2026/11/02 12:07:41 2026/11/02
【摘要】 复盘登录自动化的四类坑:二维码 ticket 需重载页面才刷新、验证码是否发出要看按钮倒计时、验证码过期与页面过期是两种错误、隐藏协议框与视觉禁用按钮会误导判断。给出同页面保活+外部取码+真实输入+显式勾选+提交后验证的稳定方案。

华为云登录排障实录:为什么二维码和验证码总在“最后一步”失效

引子

自动化脚本最容易卡住的地方,往往不是业务逻辑,而是登录。最近我在做华为云开发者社区的任务自动化时,连续踩了二维码、短信验证码、页面过期、协议勾选、按钮禁用这一整套坑。每一次看起来都“只差最后一步”,但就是过不去。

这篇文章把这几次失败的真实现象和根因完整复盘一遍,给同样在做网页自动化的同学参考。

一、二维码:生成成功 ≠ 扫码有效

第一反应是用二维码登录。流程很简单:打开登录页 → 导出二维码 → 用户用 App 扫。

但实测出现了两种截然不同的结果:

现象 实际原因
二维码图片正常显示,但扫码后无反应 二维码 ticket 已过期(服务端几分钟级失效)
页面提示“已过期”,重新生成后又能扫 二维码必须重新加载登录页才会拿到新 ticket

一个容易误解的点:我给守护进程写了“每 4 分钟重绘二维码”的逻辑,以为能续期,结果发现重绘只是把同一张图重新导出,ticket 根本没变。

教训一:刷新 UI 不等于刷新凭证。二维码这类有服务端状态的凭据,必须重新触发获取动作(重载登录页),而不是重绘图片。

二、短信验证码:按钮没倒计时,就是没发出去

二维码不稳,我改走手机号验证码。第一次的脚本“看起来成功了”——点了“获取验证码”,也没有报错,但用户始终收不到短信。

后来把页面状态打印出来才发现:按钮没有进入“重新获取 (xx)”倒计时。而在正常情况下,发送成功后按钮一定会倒计时。

继续排查,发现两个坑:

坑 1:tab 被误点。 登录页默认就是“手机号登录”,但脚本里有一段“点击‘手机号登录’切换 tab”的逻辑。这次点击反而把页面切到了密码登录——于是脚本填进了那个不可见的“手机号/邮件地址/账号名”输入框,自然发不出验证码。

坑 2:判断依据错了。 之前用“页面有没有报错”判断发送是否成功,但发送失败时页面往往什么都不提示。真正可靠的信号是按钮是否进入倒计时。

修复后,页面明确出现:

短信验证码已经发送至 188****1416,10 分钟内有效
重新获取 (56)

教训二:判断一个动作是否成功,要找服务端确认过的信号(倒计时、状态码、接口返回),而不是“页面没报错”。

三、验证码“不存在或已过期”:其实是时序问题

后来能发出验证码了,但每次提交都提示:

验证码不存在或已过期。

复盘时间线才发现,问题出在往返耗时:

发送验证码 → 通知用户 → 用户查短信 → 回复 → 脚本填入提交

这段链路一旦超过有效期(哪怕只有几分钟),验证码就作废了。

我最初以为是“页面过期”,但页面错误提示是另一个:

当前页面已过期,请刷新当前页面后重试。(0368770)

这是两个不同的错误:一个是验证码过期,一个是登录页的会话/CSRF 过期。混在一起排查,很容易误判。

教训三:把错误码/错误文案分类。验证码过期要重发;页面过期要重载页面。两者的处置方式完全不同。

四、隐藏的协议勾选框与“永远禁用”的按钮

最迷惑的一段:所有字段都填了,登录按钮却一直带着 hwid-disabled,而且有两个同名按钮——一个不可见(w=0),一个可见但文本是“登录/注册”。

深入 DOM 后发现一个不可见的协议复选框:

<input type="checkbox" name="checkboxInput" checked="false">

它 offsetParent 为 null(视觉上隐藏),但业务上必须勾选。用 JS 直接置 checked = true 并派发 change 事件:

const cb = document.querySelector('input[name=checkboxInput]');
cb.checked = true;
cb.dispatchEvent(new Event('change', { bubbles: true }));

另外,hwid-disabled 这个 class 只是视觉禁用,按钮本身 disabled 属性仍是 false,点击依然会触发校验请求(可以看到 chkHwidAccount 接口被调用)。

教训四:不要只看“按钮灰不灰”。要看它的 disabled 属性、绑定的事件、以及点击后是否真的发出了请求。

五、最终跑通的做法

综合以上,最后稳定的登录方案是:

  1. 同页面保活:发送验证码后不关闭浏览器,保持登录页存活;
  2. 外部取码:通过文件通道把验证码传进脚本(用户异步提供),避免重新打开页面;
  3. 真实输入:用键盘逐字符输入,触发前端框架的校验;
  4. 显式勾选:直接设置隐藏协议框并派发事件;
  5. 提交后确认:不仅看 URL 跳转,还要导出登录态并到目标页验证。

跑通后,登录态导出的关键 Cookie 是长期有效的:

cbc-sid       有效期约 365 天
vk            有效期约 365 天
hwid_cas_sid  有效期约 400 天

把这些存成 storage_state,后续在新浏览器上下文里复用,实测可以直接访问受保护页面,不需要反复登录。

六、小结

这次排障最有价值的四条经验:

  1. 有服务端状态的凭据都要确认时效:二维码 ticket、验证码、页面 token,各自独立过期;
  2. 成功信号要找服务端确认:倒计时、状态码、接口返回,而不是“页面没报错”;
  3. 错误要分类:验证码过期 vs 页面过期,处置方式相反;
  4. 隐藏元素与视觉样式都可能骗人:检查真实 DOM 属性与网络请求。

把这些想清楚之后,登录这一步才从“玄学”变成了可复现、可维护的工程问题。

本文基于本人在华为云开发者平台做登录自动化时的真实排障记录整理,错误文案、Cookie 名称与页面行为均来自实际观察,纯原创,欢迎交流。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。