ネモウスドットコム

エンジニア兼プロデューサーがWebサービス制作について考えるブログ

このサイトはかみさまのWebサービス制作研究所に移転しました。
こちらのサイトもぜひご覧ください。

Facebookアプリ開発におけるIE&Safariのセッション問題対策

Facebookアプリを開発するときに厄介なのがIEとSafari。 Chromeでの開発が完了し、IE&Safariでテストしていたら致命的なバグが……。

この主な理由が、ブラウザによって異なるサードパーティークッキーの扱いでした。

今回はPHPで開発したので、PHPでの対策について書きます。

サードパーティークッキーとは?

サードパーティークッキーについて、参照記事では以下のように説明されています。

クッキーの種類の2つ目は、ユーザーがアクセスしているWebサイトとは別のサーバーから発行されるクッキーです。表示しているWebページの中に、別のサーバーからクッキーを発行させる命令が記載されているのですが、こうしたクッキーは「サードパーティクッキー」あるいは「追跡クッキー」と呼ばれています。

Facebookアプリは、Facebookページ(www.facebook.com)の中のiframeによって自サーバのWebページ(www.example.com)を表示しています。 つまり、Facebookページとiframe内ページでドメインが異なります。 このように、ドメインが異なるページから発行されたクッキーをサードパーティークッキーという訳です。

このサードパーティークッキーについて、IEとSafariについてはデフォルトで受け入れを拒否しています。 これが発生し得るバグの大きな原因であり、Facebookアプリを開発する上ではこのことを解決する必要があります。

1. IE対策

IEについては、以下のようにP3Pでポリシーを宣言すればよいです。

iframeで別ドメインのコンテンツを読み込むと、そのCookieはサードパーティーのCookieとなります。IEのデフォルトでは、ポリシーが定義されていないサードパーティーのCookieは受け入れないようになっていて、P3P (www.w3.org)でポリシーを宣言すれば受け入れられるようになります。

その方法は次の通り。

if (ereg('MSIE', getenv('HTTP_USER_AGENT'))) {
    header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
}

まず環境変数より閲覧ブラウザを判定し、IEであればheaderでポリシーを宣言する。 これだけでIE対策は完了です。

2. Safari対策

Safariについては、以下の3つの方法が考えられます。

  1. パラメータを引き回す
  2. HTML5のlocalStorageを利用する
  3. ユーザ側にクッキーを受け入れてもらうよう設定してもらう

ただ、Safariのシェアは2012年5月時点で約7%程度であるため、大規模なアプリでない限り1・2の方法を採用するのはコストが大きいと思います。

3については、具体的に言うと

  1. メニューバーのSafariから環境設定を開く
  2. プライバシータブを開く
  3. Cookieをブロックの項目でしないを選択する

となります。 ユーザのブラウザがSafariであると判別された場合のみ、上記手順を示すのが手っ取り早い対策かなと思います。

ちなみに、Safariを判別するPHPプログラムは次の通り。

if (ereg('Safari', getenv('HTTP_USER_AGENT')) && !ereg('Chrome', getenv('HTTP_USER_AGENT'))) {
    // クッキーを受け入れるための手順を表示
}

関連記事

以下の記事も読んでおくと良いかも。

記事の中で書かれている、

サードパーティークッキーになるべく依存しない

という考えにはとても同意。 依存してしまうと、上述のようにIE&Safari対策が厄介です。

おわりに

こんな問題が生じるとは知らずに仕事を請けたので、ちょっとばかり大変でした。 こういった問題を把握して工数に組み込むことも重要ですね。

今回開発していて、Facebookアプリ開発はサーバサイドよりJavaScriptの方が楽なんじゃないかと思ったり。

上記問題のより良い解決策をご存知の方は、ぜひご教示ください! よろしくお願いします。