今までも不思議に思うことは多々あったのですが、EC-CUBEのセッション管理には不具合があるのを見つけてしまいました
MAX_LIFETIME(デフォルトだと7200秒)よりも早いタイミングでセッションが消えてしまう可能性があります
問題のコード
この問題はMySQLの場合のみ発生します
data/class/helper/SC_Helper_Session.php
~~~
function sfSessGc($maxlifetime) {
// MAX_LIFETIME以上更新されていないセッションを削除する。
$objQuery =& SC_Query_Ex::getSingletonInstance();
$where = “update_date < current_timestamp + '-". MAX_LIFETIME . " secs'";
$objQuery->delete(‘dtb_session’, $where);
return true;
}
~~~
この「current_timestamp + ‘-“. MAX_LIFETIME . ” secs’」が問題になります
PostgreSQLの場合
正しく2時間前の時間が指定されます
~~~
# select current_timestamp,current_timestamp + ‘-7200 secs’ ;
now | current_timestamp + ‘-7200 secs’
——————————-+——————————-
2013-03-08 15:03:59.121512+09 | 2013-03-08 13:03:59.121512+09
(1 row)
~~~
MySQLの場合
結果が文字列になっててわかりにくいのでcastしたものも追加してあります
~~~
select current_timestamp,current_timestamp + ‘-7200 secs’, cast(current_timestamp + ‘-7200 secs’ as datetime);
+———————+———————————-+—————————————————-+
| current_timestamp | current_timestamp + ‘-7200 secs’ | cast(current_timestamp + ‘-7200 secs’ as datetime) |
+———————+———————————-+—————————————————-+
| 2013-03-08 15:07:02 | 20130308143502 | 2013-03-08 14:35:02 |
+———————+———————————-+—————————————————-+
1 row in set, 2 warnings (0.00 sec)
~~~
2時間前にならずに2013-03-08 14:35:02(約30分前)の時間になってしまいました
これは、MySQLとPostgreSQLのSQLの書き方に違いがあるために起こっていることです
修正方法
MySQLを使っている人はこう書き換えればPostgreSQLと同じ結果になります
data/class/helper/SC_Helper_Session.php
~~~
function sfSessGc($maxlifetime) {
// MAX_LIFETIME以上更新されていないセッションを削除する。
$objQuery =& SC_Query_Ex::getSingletonInstance();
//$where = “update_date < current_timestamp + '-". MAX_LIFETIME . " secs'";
$where = "update_date < current_timestamp + interval -". MAX_LIFETIME . " second";
$objQuery->delete(‘dtb_session’, $where);
return true;
}
~~~
SQLで書くとこうなります
~~~
mysql> select current_timestamp,current_timestamp + interval -7200 second;
+———————+——————————————-+
| current_timestamp | current_timestamp + interval -7200 second |
+———————+——————————————-+
| 2013-03-08 15:14:01 | 2013-03-08 13:14:01 |
+———————+——————————————-+
1 row in set (0.00 sec)
~~~
自分でコミットすればいいんですが、コミッターのアカウントもパスワードもやる気も無くしちゃったので誰か開発合宿で直してコミットしておいてください(^_^;)
確認した範囲ではEC-CUBE2.4.4系から最新の2.12系まですべて影響を受けているものと思われます
参考サイト:【第34回】MySQLの日付計算 – Tech [Friday] プロモバイルエンジニアブログ
21:32 追記
早速コミットしてもらえたので次のバージョンあたりでは直っていそうです
http://svn.ec-cube.net/open_trac/changeset/22616
コメント
コミットしときましたぜ
[…] セッションで消去する対象の検索SQL文修正 http://nob-log.info/2013/03/08/ec-cube-bugs-session/ http://svn.ec-cube.net/open_trac/changeset/22616 […]