ブラウザと同じCookieを使えたほうが便利なことも多い。
ログインを解析してCookieを発行できないサイトも今後増えるだろうし。PhantomJSでChromeをオートパイロットして、その結果を使うこともあるだろう。
ChromeのCookieの場所
Mac OSX の場合、ここにCookieがおいてあります。
~/Library/Application\ Support/Google/Chrome/Default/Cookies
sqlite3なChrome のCookie。
chromeはSqlite3の塊です。Cookieにも使われています。
cookieのデータベースを開く
sqlite3 ~/Library/Application\ Support/Google/Chrome/Default/Cookies
ChromeのCookieのテーブル構造
ChromeのCookieは次のようなテーブル構造に格納されています。
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);
ChromeのCookieでの時刻
Chromeのクッキーは 1970/01/01ではなく、1601/01/01 を起点としたUTC時刻で保存されています。
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 しなくなってる。なので、コード側で対応することにする。