それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

ChromeのCookieをプログラムから使う

ブラウザと同じCookieを使えたほうが便利なことも多い。
ログインを解析してCookieを発行できないサイトも今後増えるだろうし。PhantomJSでChromeをオートパイロットして、その結果を使うこともあるだろう。

ChromeCookieの場所

Mac OSX の場合、ここにCookieがおいてあります。

~/Library/Application\ Support/Google/Chrome/Default/Cookies

sqlite3なChromeCookie

chromeはSqlite3の塊です。Cookieにも使われています。

cookieのデータベースを開く
sqlite3 ~/Library/Application\ Support/Google/Chrome/Default/Cookies

ChromeCookieのテーブル構造

ChromeCookieは次のようなテーブル構造に格納されています。

CREATE TABLE cookies
(
     creation_utc      INTEGER NOT NULL UNIQUE PRIMARY KEY,
     host_key           TEXT NOT NULL,
     name                TEXT NOT NULL,
     value                TEXT NOT NULL,
     path                TEXT NOT NULL,
     expires_utc      INTEGER NOT NULL,
     secure                INTEGER NOT NULL,
     httponly           INTEGER NOT NULL,
     last_access_utc INTEGER NOT NULL,
     has_expires      INTEGER DEFAULT 1,
     persistent           INTEGER DEFAULT 1,
     priority           INTEGER DEFAULT 1
);
CREATE INDEX domain ON cookies(host_key);

ChromeCookieでの時刻

Chromeのクッキーは 1970/01/01ではなく、1601/01/01 を起点としたUTC時刻で保存されています。

UTCを時刻オブジェクトにするrubyの場合

require 'sqlite3'
db = SQLite3::Database.new(PATH_TO_CHROME_COOKIES)

db.results_as_hash = true

begin 
    db.execute('select * from cookies '){|row| 
        row["creation_utc"] = Time.at( Time.utc(1601,1,1,0,0,0,0).to_i , row["creation_utc"] ).utc
        row["expires_utc"] = Time.at( Time.utc(1601,1,1,0,0,0,0).to_i , row["expires_utc"] ).utc
    }

ensure
    db.close
end


このように

Time.at( Time.utc(1601,1,1,0,0,0,0) , r["creation_utc"] 

として、UTC時刻を変換して上げる必要があります。

Cookie期限は実はそんなに重要じゃない。

Cookieを使うだけであれば、期限など関係なしにサーバーに送信したらいいので、細かい時刻について気に病む必要もないです。

HTTPリクエストでCookieヘッダに値が列挙できたらそれでOKです。


ブラウザのCookieを使う場面

ニコ生やニコニコ動画のように、同時ログイン数が限られている場合で、ブラウザを起動しながら使いたい場面に限られるんじゃないでしょうか。

今回はSBI証券APIを叩くときエラー状態の切り分けがしたくて使いました。

ブラウザのクッキーをプログラムからガンガン使うようなプログラムはできれば書くべきではないです、NTTのマネールックのようなものは特に・・・

できる限り、Formを解析してログインを送り込んだほうが確実です。自動実行プログラムは特にForm解析がメインだと思います。

ブラウザCookieは手軽に使えるので、やっぱり怖いよなぁと思うわけです。
ChromeにはデバッグモードONがあるので、デバッグモードONにしない限りCookieファイル読んでも解析不能とかにして欲しいですね。。。

2016-08-22 追記

Ruby の Time.at の仕様が変わってて、Timeオブジェクトを引数にした時に自動的に to_i しなくなってる。なので、コード側で対応することにする。