未登录会伪装成「未完成」:空响应、token not found 与 unknown 三种回法

举报
yd_241537561 发表于 2026/11/13 07:04:48 2026/11/13
【摘要】 同一天里会话失效两次,三种接口给出三种完全不同的回法:一个域回 200 加空 body,一个域回 HD.92010003 token not found,还有一个域把每张任务的状态写成 unknown。最危险的是最后一种——它和「还没做」在代码里长得一模一样,脚本会因此去重复做那些撤不回的动作。

无人值守脚本最难缠的不是接口复杂,是「登录态没了」这件事有三种长相。上午登录成功跑完一轮,中午再打同一批接口,实测到的三种回法如下。

一、三种回法

A. 某业务域:HTTP 200 + 完全空的 body(没有 content-type,不是登录页 HTML)
B. 成长中心:{"error_code": "HD.92010003", "error_msg": "token not found"}
   同域还见过 HD.32110001 auth error、以及字面量 not login
C. 实践中心:GET /api/growth/tasks -> {"logged_in": false,
   "tasks": [ {"today_status": "unknown", "git_bound": null, "orgs": null, ...} ]}

A 最容易误判。因为状态码是 200,任何「按状态码判成败」的写法都会把它当成成功,然后卡在下一步解析 JSON:Expecting value: line 1 column 1,报错信息完全指不到登录态。我现在的做法是在解析层显式归一:

body = (r.text or "").strip()
    try:
        return r.json()
    except Exception:
        # 实测:会话失效时网关回 200 + 完全空的 body,没有 content-type
        if not body:
            return {"error_code": "NOT_LOGIN", "error_msg": "登录态失效(空响应)"}
        if body[:1] == "<" or r.status_code in (401, 403):
            return {"error_code": "NOT_LOGIN", "error_msg": "登录态失效(返回登录页)"}
        raise

把「空响应」和「返回登录页」都收敛成同一个错误码,上层才只用一种判断。这一步做完,日志里再也不会出现「Expecting value」这种看不出根因的行。

二、C 种回法为什么最危险

未登录的时候,任务列表接口照样返回任务对象,字段还在,只是状态变成 unknown、配置类字段(git_bound、orgs、repos)全为 null。如果脚本这么写:

if task["today_status"] != "done":
    do_star()      # 没做完就去做一遍

那么未登录那天它会把撤不回的动作重做一次(Star 是不可撤销的),并且第二天还会再来一次。正确的顺序是先确认会话活着,再读状态:

if not payload.get("logged_in"):
    return "未登录,本轮既不判状态也不执行动作"

if task.get("evaluator") == "external_check" and task.get("git_bound") is None:
    return "绑定信息读不到,同样是未登录,不是任务没做"

判据要挑那种「只有登录了才可能有值」的字段:登录标志、绑定账号名、积分是否是整数。beans=None 和 beans=1270 的差别,比任何错误码都直白。

三、B 种回法要区分令牌轮换与真失效

CSRF 类令牌会轮换,第一次 token not found 常常只是本地令牌旧了。我的处理是强制刷新一次再打第二次,只有第二次仍然报错才算会话死。如果不做这个重试,会把大量「一次刷新就能救」的情况误判成需要重新登录,脚本于是频繁走整轮登录流程,反而更容易撞上风控。

四、还有一类不是登录问题,别去重登

最难分辨的是「接口本身已经下线」。有一阵某个每日福利接口回 4000 invalid channel, group not found,后来同一个口改成回 200 + 空 body,看起来跟登录失效一模一样。判断方法不是换个更仔细的登录,而是用刚重登成功、令牌齐全的新会话再打一次:如果新会话也是同样回法,那就不是 Cookie 的事。我这次就是这样确认的——新登录态下余额接口仍然回空、领取仍然回同样错误,于是把这条从「每天报登录失效、并顺手触发整轮重登」改成「如实播报厂商侧已下线」。省掉一次无效重登,也就少一次被风控盯上的机会。

四种回法收敛成一句话:先证明会话活着,再解释状态;证明不了就什么都不做。未登录和未完成长得越像的接口,越要把「读状态」和「执行动作」之间插一道登录校验。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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