Android WebViewの cookieではまった。
仕事でハイブリッドアプリケーションを使っていてはまったので、他山の石となるべくメモ。 あと、これは 4.2.2 (Jellybean) でのことなので、4.4の Chromiumベースの WebViewでは 話が違っている可能性も大。
WebViewの session cookieは、かなり生存力高くリブートしても消えない!
Session cookieっていうのは、expireが指定されておらず、ブラウザのセッションが終わったら (= PCではブラウザアプリが終了したら) 消えてなくなる cookieです。 ところが Androidではこれがほっといても消えない! Activityがなくなっても、あまっさえデバイスが再起動しても消えない!まあ、考えてみるとスマフォでは「セッションってなんだ?アプリケーション終了って?」って話なので、セッションなんて環境依存したものに依拠した仕様がどうかと思うけど、リブートしても残ってるのはややびっくり。
これは StackOverflowにもしっかり書いてあります。
You are correct, session cookies do not expire automatically in the lifecycle of a WebView. If you are seeing issues with this, you can always clear all of your cookies or overwrite your session cookies explicitly with an empty value.
実際に、下の実験スクリプトで「記録」ボタンを押して、数分待ってからリブートしてこのページを訪れれば、先ほど設定した値が残っているはず (session cookieなのに!)。ちなみに数分待たなきゃいけない理由は後述。
実はこれに直接はまったわけじゃない。本当は cookieが消えるバグがあって、その原因は Session cookieだからだろう!と追っていったら単なる勘違いでした。でも間違った方向に進んで数時間無駄にした。
WebViewの cookieは、すこし待たないとフラッシュに保存されない!
よく見れば CookieSyncManagerに書いてあるんですが、Cookieの永続化は非同期に裏でやってるので、Cookieを書き換えた瞬間にアプリが死んじゃうと、変更したはずの cookieが次のセッションに反映されない。
今やってるやつは、cookie書き換えた直後に 強制アップデートしてたりするので、そこでプロセス終了して書き換えた cookieがどこかにいってはまったのでした。
もしもほかに強制アップデートさせることがあるひとがいたらご注意を。あんまりいないと
前節の実験のところで「数分待って」と書いたのもこのせいです。待たないと永続化されないので、再起動後には cookieは残ってなく session cookieが消えてめでたいように見えるのです。
この永続化ディレイは、実験スクリプトで「記録」ボタンを押してすぐにブラウザアプリを殺す (アプリ履歴で横スワイプする) と確認できます。
実験スクリプト