ありがとう。また会おう。

まぁゆるりとやっていきますよと。

今時の携帯ブラウザCookie事情。

すいません、しばらくぶりになってしまいました。
ブログのネタはたくさんある(はず)なんですが、
やはりMixi日記みたいに、駄文を垂れ流してればいい(笑)のとは違って
書こうとしてる内容が技術的に正しいか、裏とれてるか、とか、
誤解される表現がないかとか、いろいろ考慮することがあって
大量生産はできないっすね。。。
まぁ、その分、なるたけ質の良いエントリーを提供しようとは心がけていますので、気長にお待ちいただければとf(^^;;;


さて、今回のお題は、携帯ブラウザのCookieについて。
先日のエントリーで、個体識別番号どうよ?みたいな話もあって、
ちゃんとPCと同じようにCookie使いましょう・・・って僕自身も思っているんですが・・・

これがまた、地味な落とし穴がいろいろあって、悩まされるんです。。。

てことで、あまり他の人のブログにみかけない、携帯Cookieの地味な落とし穴について書きたいと思います。

DoCoMo

え〜、いきなりですが語ることありません(爆)
なぜなら、DoCoMoの携帯ブラウザは全端末Cookie非対応なので*1

先日のエントリにも書きましたけど、これ、もう「脆弱性」って言っていいと思うんですけどね。。。
・・・ちょっと言葉違うかな。
じゃあ「セキュリティ上の重大な懸念」ってのでどうでしょう。
そういうのをもっと携帯コンテンツプロバイダーのキーマンや、セキュリティの権威の方が、もっともっと声を大にして、キャリアに圧力かけてほしいんですけどね。。。

Au(KDDI)

Auは現時点でezwebに接続可能な端末は、全てCookie対応しています。
これは非常にありがたい・・・んですが・・・
やはり一筋縄ではいかないのが、携帯ブラウザ。。。


(1)SSL・非SSLをまたいではCookie利用できない
これは、Au端末のCookieファイルの保存方法に由来する問題なんですが、
SSLCookieは、ezwebのゲートウェイサーバで保存するのに対し
SSLCookieは、端末に保存します。
なので、非SSLSSLをまたいでCookieを引き継ぐことができません。
必要に応じて、プログラム側で詰め替えるなりの考慮が必要です。


(2)Cookieの有効期限
そして地味に嫌なのがこれ。
下記参考サイトにもあるとおり、Au端末のCookieのデフォルトの有効期限は24時間と結構長めです。
そして、これまたやっかいなことに、有効期限の設定は
「HTTPレスポンスヘッダの「Set-Cookie」フィールドの「max age (有効残存秒数) 」で指定」
とあるんですが、実はこの方法でしか有効期限が設定できません
PCサイトでよくある他の指定方法(Expireヘッダとか)では対応していません。


さらにやっかいなことに、これはPHPの問題ですが
PHPのsession_set_cookie_param()関数の第1引数lifetimeは、Set-CookieレスポンスヘッダのMax-Age属性を送出してくれません*2
なので、header()関数などで出力する必要があります。
直接header()関数使って上書いてもいいんですが、
僕は出力予定のレスポンスヘッダを取得して、追記する感じでロジック組んでます。
具体的にはこんな感じです:

<?php
if (キャリアがKDDIなら){
    $response_headers = apache_response_headers();
    if (isset($response_headers['Set-Cookie'])){
        header('Set-Cookie: ' . $response_headers['Set-Cookie'] . ' ;Max-Age=1800');
    }
}

また、Au端末のCookieでは、PCブラウザのような「ブラウザを閉じるまで」を表す「lifetime=0」が使えません。
もっともこれは、非SSLCookieを、端末ではなくゲートウェイサーバで管理している以上、避けられない仕様なんでしょうが。。。


【参考】
http://www.au.kddi.com/ezfactory/tec/spec/cookie.html

SoftBank

SoftBankCookieは、AuよりはPCの仕様に近いと思います。
まず、対応端末は3GC端末です。
C型・P型は対応していないので、セッションIDなどはDoCoMo同様GETパラメータとして引き回すしかありません。
もっとも、すでにこれら第2世代端末は、2010年3月末でサービス終了、とSoftBankから発表されてますので、これから制作するサイトは積極的に第2世代端末を切っていった方が得策だと思います*3


Cookieは端末にて保存します。
ただし、別の理由で、SSL・非SSLはまたげません。。。

これはSoftBankSSL仕様に起因するんですが、
SoftBank端末でSSLのドメインにアクセスすると、単にhttpsになるのではなく、
SoftBankの中間ゲートウェイを介してSSL接続することになります。
例えば、https://example.com/index.html へのリンクは
https://secure.softbank.ne.jp/example.com/index.html
となります*4
従って、ドメインが変わってしまうので、Cookie引き継げないんです。。。


そしてもう1点。これまた地味な制限が。。。

実はSoftBankCookieにはこんな仕様があります。


SoftBankの携帯ブラウザは、自発的にCookieは送出しません。サーバからのレスポンスヘッダ Set-Cookie を受け取ると、次のリクエストからCookieを送出します」


通常、PCやAuのブラウザもそうですが、Cookieは、アクセスするドメインやパスなどの条件が合致すれば、サーバの要求がなくてもブラウザが自発的に送出しますが、SoftBankはそうじゃないんです!

具体的にこれがどういうことになるかというと、
Cookie、よりわかりやすく言えば、セッションを使い始めたいページで
session_start() をしても、そのリクエストでは、Cookieヘッダが送出されてないので、ちょっと挙動がおかしくなります。
具体的には、session.use_only_cookies や session.use_trans_sid などの設定値にもよるんですが、セッションがちゃんと開始できなかったり、
最初の1回だけ、セッションIDがGETパラメータで渡ったりしちゃいます。

これの回避策は、「セッションを使い始めたい『1つ前の画面』で session_start()すること」くらいしかなさそうです。。。


ちなみに、SoftBankでは、lifetime=0(ブラウザ閉じるまで有効)の設定は可能です。このあたりはPCと同じで使いやすいんですけどね。。。


【参考】
ソフトバンクモバイル・HTTP仕様書
ソフトバンクモバイル・MOBILE CREATION(http://creation.mb.softbank.jp/)内で配布*5

まとめ

てことで、細かい落とし穴がたくさんあって、まだまだ携帯Webはいばらの道ですが、とりあえず気をつけなきゃいけないのは。

  • SSLと非SSLをまたぐときは要注意。基本引き継げない。
  • Auはデフォルトの有効期限が長い(24時間)。かつ期限の設定方法が限られている
  • SoftBankはセッションを使いたいページの「1つ前」からsession_start()する
  • DoCoMoは・・・・・(泣)

てとこでしょうか。
というかDoCoMo!!本当にCookieとっとと対応してくれ!!

*1:未確認ですが、フルブラウザは使えるんでしょうかね?ここでの話は全て携帯専用ブラウザ(キャリア公式サイトが見れるブラウザ)のことです

*2:これは早いとこPHPに対応してほしいところです

*3:既存サイトもコストに見合わない場合がほとんどなので切ったほうがいいかと・・・というか切りましょうよ・・・

*4:例外として、メール本文に記載されてるURLをクリックした場合は、ゲートウェイを介さないそうです。詳細は http://creation.mb.softbank.jp/web/web_ssl.html を参照ください

*5:会員登録(無料)が必要です