每次重启Mac,都是同样的折磨。打开Playwright控制的Chrome窗口,七个发布平台的标签页全被登出,接下来十分钟就是重复输入密码、点Google账号选择器。Zenn、dev.to、note、Substack、X、LinkedIn、Search Console,全部重来一遍。
我一个人运营Codens的GTM,整个发布流程全靠Playwright驱动。npx @playwright/cli@latest启动的是带持久化配置的真实Chrome,一堆小脚本负责把标题和正文塞进各个编辑器。运行很顺畅,直到主机重启——/tmp/chrome-pw-corevice这个user-data-dir跟着/tmp一起蒸发。
我终于坐下来彻底解决了。成果是一个30行的shell脚本,每次启动时把日常用的Chrome配置克隆到Playwright的临时目录,还有两个关键技巧让cookie真正能解密。这篇说的就是这两个技巧。
最明显的办法为什么不行?第一反应肯定是直接复制:
cp -r ~/Library/Application\ Support/Google/Chrome/Default \
/tmp/chrome-pw-corevice/Default
跑完启动Playwright,Chrome看起来确实加载了配置。历史记录在,书签在,扩展在。但所有网站都是登出状态,DevTools里cookie jar要么空的,要么塞满了一堆无法认证的cookie。
问题在于Playwright启动Chrome时加了两个我挖代码才知道的flag:
--use-mock-keychain
--password-store=basic
这两个flag让Chrome完全绕过macOS钥匙串,用硬编码的mock密钥来加密cookie和密码存储。从Playwright的角度这是合理的默认设置——CI runner没有真钥匙串,无头容器也没有,mock让Chrome能在没有Keychain Access的环境里可靠启动。
但对我来说这完全搞反了。日常Chrome写到磁盘上的cookie,用的是真钥匙串密钥,就是Chrome首次安装时存在我登录钥匙串里那个"Chrome Safe Storage"。复制过来的cookie还是用这个真密钥加密的。Playwright的Chrome带着mock密钥启动,尝试解密,得到乱码,默默把所有cookie标为无效。
我试过storageState,这是Playwright文档推荐的做法。从一个上下文导出cookie和localStorage,注入到另一个。有些网站能跑通,有些直接挂掉。Substack卡在Google SSO重定向,认证握手永远完不成。Note的编辑器要一个跟会话cookie绑定的CSRF token,storageState虽然抓到了,但服务器不认, presumably是因为会话绑定了原始UA指纹。第三个网站又以另一种方式失败后,我放弃了storageState,回到克隆整个配置的路子。
热门跟贴