2017年5月6日土曜日

Codeigniter で他システムとセッション共有する場合に、$_SESSION が消えてしまう

オフィス狛 技術部です。

同じドメイン配下に存在する別システム(Codeigniter ではないPHPを使ったシステム)と、
セッションを共有する・・・つまり、$_SESSION で値をやりとりする事になったのですが、
Codeigniter 側で $_SESSION から値を取ろうとすると、空になっている現象が発生しました。
単純には行かないのですね、やっぱり。

※ちなみに、Codeigniter のバージョンは 3.1.2 です。

1)セッションIDを調べてみる

セッションIDが変わってしまって、違うセッションを見ているのかと思い、
$_COOKIE を調べたところ、session_id は同じでした。
(同じドメインですし、敢えてセッションを変えるような設定もしていないので)
セッションIDが同じで値が取れないのであれば、どこかで値を消している、という事になります。

2)Codeigniter を使用していないPHPシステムで試してみる

Codeigniter を使用していない、Webサーバー上に置いただけのPHPファイルで試してみたところ、
$_SESSION から値が取れる事が確認出来ました。
という事は、Codeigniter でセッションを消している事になります。

3)Codeigniter の Session.php を調べてみる

というわけで、Codeigniter の System/libraries/Session に存在する、
「Session.php」を調べてみました。

105行目付近に、
$class = $this->_ci_load_classes($this->_driver);
という記述があり、このタイミングで driver を変更しているため、
この処理以降に設定した driver のセッションを参照しているのではないかと予想できます。

※実際、この処理の直前では $_SESSION の値は取得できたが、
直後には値が消えていた事を確認しています。

4)対応方法(暫定)

とりあえず、先程の記述の直前で、
// 追加ここから
session_start();
$session = $_SESSION // 値を一時変数に格納
session_write_close();
// 追加ここまで
$class = $this->_ci_load_classes($this->_driver);
と記載します。実は、session_start 自体はもっと後で行うのですが、
ここで一旦スタートさせて、$_SESSION の値を退避しておきます。
(closeも忘れずに)
そして、今度は、元々あった「session_start」(150行目近辺)の後に、
session_start();
//追加ここから
$_SESSION = $session; // 値を一時変数から再設定
// 追加ここまで
と追加する事で、他システムで設定された $_SESSION を利用する事ができます。

5)本当はどう対応するべきなのか

実は、弊社側のシステムは、セッションをDBに保存する設定にしています。
そしておそらく、他システム側は、セッションはファイル保存していると思います。
(弊社保有のシステムでは無いので、実際は分からないですが・・・)
ですので、$_SESSION が消えてしまうのも、当然と言えば当然なのです。
だとするならば、
こちら側の driver を「files」にして、保存パスを共有した場合、うまくいきそうな気がします。

※ちなみに、設定出来る driver は、本家サイト(翻訳版)に記載してありますが、
  • files(デフォルト; ファイルシステムベース)
  • database
  • redis
  • memcached
となっています。(自分でカスタムセッションドライバも作成可能です。)

今回は、テスト環境含め、弊社が触れる環境では無いので、
色々試せないですが、いずれ社内に環境作って試してみようと思います。


,

0 件のコメント:

コメントを投稿