読者です 読者をやめる 読者になる 読者になる

Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

CakePHP2でSessionのcore.phpの設定が上書きされない

CakePHP2.2.3での話。おかしいこんなことは許されない・・・・

CakePHPのセッションの設定はcore.phpでこんな感じで設定することでデフォルトの設定をオーバーライドできると書いてある。

<?php
Configure::write('Session', array(
    'defaults' => 'database',
    'cookie' => 'my_app',
    'timeout' => 4320 //3 days
));

//http://book.cakephp.org/2.0/en/development/sessions.html

上記のようにDB管理にしてクッキーの名前と実際に発行されるクッキーを見てみるとCookieの名前がCAKEPHPでクッキーの有効期限が4時間になってた。おいおい、デフォルトのままじゃん・・。bootstrap.phpに書いてもあかんかった。ちなみに、デフォルトの設定はLib/Cake/Model/DataSource/CakeSession.php#_defaultConfigメソッドに記載されている。

<?php
$defaults = array(
	'php' => array(
	'cookie' => 'CAKEPHP',
	'timeout' => 240,
	'ini' => array(
	'session.use_trans_sid' => 0,
	'session.cookie_path' => self::$path
)

セッションはDBに入れているのだが、database上の有効期限は4時間になっているけれどsession.cookie_lifetimeの設定は0だし、session.gc_maxlifetimeの値が24分のまま。でも、不思議なことに実際に発行されたCookieの生存時間は4時間。これ、どっちが強いんだろう。実際に4時間でクッキーもらってるから、たぶん前者っぽい。クッキーの有効期間が切れちゃってるならセッションIDがクライアントからもらえないからセッション切れるよね・・・そりゃね。

CakephpでセッションをDBで管理している場合は、id,data,expireの3つのキーを持ってる。で、リクエストがくるとcookieに保管されたハッシュのIDで引いて、json形式で保存されれいるdataの有無を確認してあればOK、なければログアウトされたという事になり、expiresで指定された時間よりも短い生存時間のSessionのレコードがDELETEされることでgcのような振る舞いをしている。

うーん・・・とにかく上書きされないのは何なのだろう。最近セッションが断続的に切れることがあり、Cookieの生存時間も4時間でtimeoutも4時間なのにログインされていないことになってしまってる。困ったなぁ。引き続き色々試してみる。

追記(2013/02/20 15:13)

原因がCakePHPのプラグインだったとは・・・。MASA-PさんのMASA-P/cake_ktai_library ? GitHubだった。このComponentsの読み込みをコメントアウトしたらcore.phpのセッション設定が有効になった。バージョンは0.5.1。KtaiLibraryのコードをまじめに追っていない僕が悪かった。

で、追っかけていったら、携帯でセッション管理を行う場合はセッションの設定がしっかりと上書きされていた。

<?php
function initialize(&$controller){
       //中略
	if($this->_options['enable_ktai_session']){
			$this->_options['session_save'] = Configure::read('Session');
			$params = array(
				'defaults' => Configure::read('Session.defaults'),
				'checkAgent' => false,
			);
			if($this->_lib3gk->is_imode()){
				$params['cookie'] = $this->_lib3gk->_params['imode_session_name'];
				$params['ini'] = array(
					'session.use_trans_sid' => 1,
					'session.use_only_cookies' => 0,
					'url_rewriter.tags' => 'a=href,area=href,frame=src,input=src,form=fakeentry,fieldset=',
				);
				if(Configure::read('Security.level') == 'high'){
					Configure::write('Security.level', 'medium');
				}
				
			}
     //ここで上書きされちゃうと携帯のセッション管理を有効に
     //してる場合は全てのクライアントで$paramsの設定に置き換わる。
     //imodeの{}の中に入れれば回避できるね、とりあえず。
     Configure::write('Session', $params);
	}		
}

ここまでくれば解決できたも同然。Configure:Writeしてる場所を書き換えるだけ!