登录态莫名失效:实测会话与出口 IP 的绑定关系
现象
前一天下午在控制台登录过,第二天上午打开页面,右上角又是「登录」按钮。同一台机器、同一个浏览器 profile,中间没清过 cookie,也没改过密码。
这类「登录态莫名失效」很容易被归因到「cookie 过期」,但这次不是。下面是完整的排查过程和结论。
第一步:确认 cookie 还在不在
Chrome 的 cookie 存在 profile 目录下的 Network/Cookies(SQLite)。浏览器运行时该文件被独占,先关掉浏览器再复制一份来查。
cp <profile>/Default/Network/Cookies /tmp/ck.db
sqlite3 /tmp/ck.db "select host_key, name, expires_utc from cookies where host_key like '%huaweicloud%'"
结果:125 条相关 cookie 全在,长期票据的过期时间远在几个月后。所以不是 cookie 被清或过期。
第二步:关浏览器到底会不会丢登录
对照组 A,全部用同一个出口(国内直连):
- 直连状态下登录成功
- 关闭浏览器
- 几分钟后重新打开同一 profile
结果:登录态保持,页面直接显示用户名和积分。
结论:正常关闭浏览器不会丢登录态。硬杀进程才可能丢,优雅关闭会把票据落盘。
第三步:换一个变量——出口 IP
当天真正出问题的那次,时间线是这样的:
| 时间 | 出口 | 操作 | 结果 |
|---|---|---|---|
| 15:16 | 国内直连 | 点「获取验证码」 | 被风控拦,提示操作存在风险 |
| 15:2x | 美国代理 | 重新登录 | 成功 |
| 16:20 | 国内直连 | 打开控制台 | 变成未登录 |
中间只改了一个变量:出口 IP。用代理 IP 完成登录后,回到国内 IP 带同一份 cookie 访问,服务端判定会话异常,直接把登录态作废。
这也能解释另一个容易混淆的现象:风控拦截和会话失效是两件事。风控挡的是「发验证码」这个动作,换个出口就能过;而换出口登录之后,出口又必须固定下来,否则下一次访问就会被判定异常。
一个会骗人的登录判据
排查过程中还踩了一个坑。当时用「页面上有没有登录按钮」判断登录态:
const logged = !document.querySelector('a.btn.js-login');
这个判据是错的。登录之后该元素依然在 DOM 里,只是宽高被置为 0:
a.btn.js-login → exists: true, width: 0, height: 0
结果是把「已登录」误判成「未登录」,多走了一遍登录流程,白等一条验证码。
可靠的判据是看业务数据:页面上的积分数字、用户名,或者元素的实测宽高。
const w = document.querySelector('a.btn.js-login')?.getBoundingClientRect().width ?? 0;
const logged = w === 0;
可复用的排查顺序
- 查 cookie 是否还在:
sqlite3 Cookies "select count(*) from cookies where host_key like '%域名%'" - 确认关闭浏览器是否影响:同出口登录 → 关闭 → 重开 → 看是否保持
- 核对出口 IP:
curl -s ifconfig.me,与登录时的出口比对 - 三步都排除后,再怀疑票据过期或服务端主动踢下线
实践建议
- 固定出口:登录用哪个网络,后续操作就用哪个。中途换网络(切代理、开 VPN、手机热点)都可能让会话失效。
- 用代理绕风控是有代价的:绕过之后必须全程同一个节点。代理软件自动切换节点,同样会触发失效。
- 自动化脚本要记录登录时的出口 IP,掉登录时先比对,能省掉大半排查时间。
- 判据看业务数据,不看控件存在性:按钮、菜单这类元素常被保留在 DOM 里只做隐藏,用它们的存废判断状态并不可靠。
以上现象和结论来自一次真实排查,环境是 Chrome 浏览器与华为云控制台。其他站点未必完全一致,但「会话与出口 IP 绑定」这个机制在多数云平台上都存在,排查顺序可以照搬。
- 点赞
- 收藏
- 关注作者
评论(0)