birdChromeのcookieをJSON形式で書き出す

自分の使っているChromeに保存されているcookieを、例えばPlaywrightのstorageStateとして読み込めるような形のJSONで書き出す方法を調べてみたら、簡単にできそうなのに意外に情報がなく手間取ったのでここに記録。最終的にはChatGPT君に教えてもらいましたが、かなりHackishな方法+教えられた通りのままでは動かなかったのでちょい頭を使いました。しかし君、どこでそんな方法を学んだんだい?w

まずそもそもの前提として、

  • ChromeのDevToolsを使い、ApplicationStorageCookies を見れば、対象のdomainに関連するcookie全てが確認出来るが、ここから外へまとめて出力する手段は提供されていない
  • そもそも HTTPOnly flagの立ったcookieはcontent contextのJavaScriptからはaccessできない。Extensionのbackground.js側からはChrome Cookie APIを経由すればaccess出来るが機能拡張(Extension)を作る必要がある

という状況があります。DevToolsに特定domainのcookieをまとめてexportする機能があればあとはそれをconvertするだけで済んだんですが、おそらく悪用を恐れたのかそういった機能は今は提供されていませんでした。

ChatGPT君曰く、最初はDevToolsのsnippetを使えば出来るかも?なんて言っていたんですがここも所詮content contextのため全てのcookieを得ることは出来ず、そのままダラダラとAI君と何度かやりとりしていたところ、

  1. まず上で書いたように対象のsiteを表示しつつDevToolsを開き、Application/Storage/Cookiesへ行く
  2. そこでおもむろに再び Ctrl+Shift+I を押して「DevToolsのDevTools」を開く(!)
  3. その2つ目のDevToolsのconsoleで 下記のようなJavaScript codeを実行する
(() => {
  const cookies = [];
  document.querySelectorAll("table[class='data'] tbody tr").forEach(row => {
    const cells = row.querySelectorAll("td");
    cookies.push({
      name: cells[0]?.innerText,
      value: cells[1]?.innerText,
      domain: cells[2]?.innerText.startsWith(".") ? cells[2]?.innerText : `.${cells[2]?.innerText}`,
      path: cells[3]?.innerText || "/",
      expires: cells[4]?.innerText === "Session" ? -1 : new Date(cells[4]?.innerText).getTime() / 1000,
      httpOnly: cells[6]?.innerText === '✓',
      secure: cells[7]?.innerText === '✓',
      sameSite: cells[8]?.innerText || "None"
    });
  });

  const storageState = { cookies, origins: [] };
  console.log(JSON.stringify(storageState, null, 2));
})();

という、ちょっと驚くべき方法を教えてくれました。これ、DevTools上に表示されているcookieであればDevToolsのcontent contextから読める、というほとんど裏技的なテクニックを使った方法です。なおPlaywrightの storageState.json にはcookieの他にlocal storageに保存されているentryなども含まれますが、それらも上記と同じテクニックを用いて簡単に手元のbrowserのものをJSON化することが出来ました。マジかよ。