964 字
5 分钟
三个平台,三套 Cookie,一堆坑

社交存档要访问三个平台,每个平台认的东西都不一样,也都不肯好好说。

各自要什么#

平台必需项特别要求
微博SUB必须是 m.weibo.cn 的,不是 weibo.com 桌面站的
Xauth_token + ct0两个都要,缺一个就是游客态
Instagramsessionid只认这一个,不支持用户名密码登录

微博这个坑我踩过:从 weibo.com 复制出来的 Cookie 里也有 SUB,看起来一样,但拿去请求 m.weibo.cn 的接口就是不认。移动端和桌面端是两套会话。

最初只有「每个平台一个 Cookie」的设计。测试多账号的时候立刻出问题:缓存完 A 用户,切到 B 用户,用的还是 A 的会话。

改成 per_user 键,格式是 platform:userId:

"cookies": {
"per_user": {
"instagram:username": "sessionid=...",
"twitter:123456789": "auth_token=...; ct0=..."
}
}

取值顺序是:先找 per_user,没有就回退到平台全局键。全局键是「这个平台我登的谁」,per_user 是「这个用户我要用谁的登录态」。

顺便说一个细节:验证 TTL 的存储用的是对象数组而不是 Map 加字符串 key。因为 userId 里可能有 : 或者别的特殊字符,用 platform:userId 拼成字符串 key 再拆分解析,迟早切错位。

坑二:验证太勤,网络一抖就弹登录框#

每次切换任务都去 x.com / instagram.com 打一次远端校验,网络稍微抖一下,就返回失败,界面弹登录窗。你根本没掉登录态,只是刚才那次请求超时了。

解决办法是进程内 30 分钟 TTL:任务完成、或 checkCookie 明确返回有效之后,30 分钟内信任本地缓存,不再打远端。

浏览页也加了短路:ensureCookie 先问「最近验证过吗」,命中就直接跳过校验。

Edge 导入是个很实用的功能——不用手抄 Cookie。但它写的是平台全局键。

早期版本顺手把该平台下所有 per_user 也一并更新了。结果是你为某个号单独准备的登录态,被一次导入全冲掉。

现在只更新 cookies[platform],per_user 一个不动,导入完清掉这个平台的 TTL 记录,下次任务重新校验。

坑四:X 的 ct0 会自己换#

这是最阴的一个。

X 的 ct0 是 CSRF token,会轮换。auth_token 不变。gallery-dl 在下载过程中会刷新 ct0。

于是你缓存完 A 用户,本地存的还是那个旧 ct0;下一个任务用 B 用户,同一个 auth_token,带着过期的 ct0,直接失败。

现在的做法:gallery-dl 刷新后的会话 Cookie 写到 {root}/twitter/.session-cookies.txt,同一个 auth_token 换用户时沿用这份。任务结束再写回设置和缓存页输入框。

另外批量队列每个任务开始前会重读一次最新 Cookie,不用入队时的快照。

坑五:Instagram 的应用内登录分区#

应用内登录会往一个 Electron partition 里存 sessionid。有个看起来理所当然的逻辑:缓存前把分区里的 Cookie 同步到设置里。

问题是切到另一个 IG 账号时,分区里还是上一个的 sessionid,一同步就把 per_user 里这个账号的凭据覆盖了。

现在改成:缓存里已有可用 sessionid 就信任它;只有缓存为空或不可用时,才从分区回填。

坑六:Cookie 不要出现在命令行#

python xxx.py --cookie "auth_token=...; ct0=..." 会把整个 Cookie 写进进程命令行,任何能看进程列表的程序都能读到。

改成走临时文件 --cookie-file,用完删掉。


这套东西最后散在四处:session.js 的可用性判断、electron/cookie-rules.js 的平台规则、cookie_check.py 的远端校验、cookie-validation.js 的 TTL。三处平台规则必须保持一致,改一个地方就得三个一起改。

三个平台,三套 Cookie,一堆坑
https://mssworld.me/posts/cookie-management/
作者
m.s.s
发布于
2026-10-25
许可协议
CC BY-NC-SA 4.0