【開発実録】ある日突然セッションが切れた話 – CakePHPコアファイルの深層へ

CakePHP

導入

このブログのキャッチコピーは「未来の自分のための技術メモ、時々あなたのためのヒント。」ですが、今回は過去の自分が格闘したデバッグの記録が、今まさに同じ問題で悩んでいるあなたの「ヒント」になるかもしれません。

エンジニアなら誰しも、「どう考えても説明がつかない…」という奇怪なバグに遭遇した経験があるかと思います。

今回は、古いバージョンのPHPフレームワーク「CakePHP 1.3」で、httphttpsが混在するサイトを構築した際に直面した、そんな不思議な「セッション切れ」問題の調査から解決までの一部始終を、探偵物語のようにお届けします。


事件の概要:消えるセッションCookie

まずは、事件の概要です。

ECサイトの一部ページのみを非SSL(http)にする必要があり、https-とhttpをページごとに行き来するサイトを構築していました。すると、以下のような奇妙な現象が発生しました。

  1. httpsのログインページからログイン
  2. httpsの会員ページに遷移(ここまではOK)
  3. httpの一般ページに移動
  4. 突然ログアウト状態になり、ログインページに強制送還される

ブラウザの開発者ツールで調査すると、httpsからhttpへ移る瞬間に、セッションを維持するためのCookieがきれいに消え去っていることが判明しました。これが事件の第一発見です。


第一の容疑者:session.cookie_secure

httphttpssをまたいでCookieを共有するには、PHPの設定session.cookie_securefalse(無効)になっている必要があります。この設定がtrueだと、Cookieはhttps通信でしか送られなくなり、httpのページでは使えません。

「原因はこれに違いない!」と確信した私は、CakePHPの設定ファイルapp/config/core.phpに、この設定を強制的にfalseにする記述を追加しました。

Configure::write('Session', array(
    'ini' => array(
        'session.cookie_secure' => false,
    )
));

これで解決するはずでした。しかし…症状は全く改善しませんでした。

設定ファイルで書いたはずの指示が、なぜか無視されているのです。


真犯人を追え!フレームワークの深層へ

設定が効かない以上、容疑者はCakePHPの内部にいると判断。私はフレームワークのコアファイル、cake/libs/cake_session.phpに足を踏み入れました。

そして、ついに「犯行現場」を発見したのです。

// ...
$iniSet = function_exists('ini_set');
if ($iniSet && env('HTTPS')) {
    ini_set('session.cookie_secure', 1); // ← コイツが犯人だ!
}
// ...

これは衝撃的な事実でした。CakePHP 1.3は、httpsでのアクセスを検知するたびに、開発者の設定をすべて無視して、問答無用でsession.cookie_secureを有効にしていたのです。これでは、設定ファイルでいくらfalseと叫んでも、声は届きません。


事件解決、そして得られた教訓

原因が特定できれば、解決は目前です。この強制設定を無効化することで、セッションは無事に維持されるようになりました。(ちなみに、このおせっかいな挙動は、CakePHP2以降ではちゃんと修正されています。)

この事件から得られた教訓は、

  • フレームワークを盲信するな: 便利さの裏には、時として予期せぬ「仕様」が隠れている。
  • 設定が効かない時は、ソースコードを読め: 結局、最も信頼できるドキュメントはソースコードそのものである。
  • 古いシステムには、歴史的な経緯が眠っている: なぜこのような実装になったのか、その背景を想像するのもまた一興。

まとめ

今回は、古いCakePHPで発生した不思議なセッション切れ問題のデバッグ記録をご紹介しました。

一見すると不可解なバグも、地道に証拠(ログ)を集め、容疑者(コード)を追い詰めていけば、必ず真相にたどり着けます。

この記事が、今まさに困難なデバッグに直面しているあなたの、問題解決の「ヒント」になれば幸いです。

コメント

タイトルとURLをコピーしました