Регенерация Session Id в Symfony - фича или баг?
Изчучая систему работы с сессиями и процесс авторизации пользователя на сайте замечаю что пропадают данные сессии. Исчезают аттрибуты, которые хотелось бы оставлять в ней и после того как пользователь разлогинился или залогинился. Что происходит в объекте sfBasicSecurityUser, когда мы вызываем метод sfBasicSecurityUser->setAuthenticated(false) ? Я пробую разобраться в этом, даже нахожу интересный обход проблемы, однако проблема куда глубже чем казалось.
На мой взгляд в симфонии переборщили с объектом sfBasicSecurityUser, заложив регенерацию ID сессии пользователя при манипуляциях с credentials и изменении статуса аутентификации. Эта регенерация по странным причинам срабатывает коряво, теряя драгоценные данные. Потеря данных меня не устраивала ни в одном проекте, пусть даже это всего лишь сессия.
На форумах и сайте php.net об этом пишут и пытаются обходить кто во что горазд. Я перешёл на sfPDOSessionStorage, думая что файлы заблокированы от быстрых запросов к файловой системе, но в таблицах так-же плодятся новые чистенькие сессии. После многих попыток вклинится в забор данных из старой сессии, остановился на том чтобы просто выключить злосчастную регенерацию.
Создаю файл в папке lib, называю mySessionStorage.class.php, переопределяю в нём два метода. Я расширил этим классом sfSessionStorage, но можно так сделать с любым стандартным обработчиком сессии: sfPDOSessionStorage, sfMySQLSessionStorage или sfPostgreSQLSessionStorage.
/**
* Adds option for turning off regenerate session id
*
* <b>parameters:</b> see sfSessionStorage
*
* @package symfony
* @subpackage storage
* @author Mathew Toth <developer@poetryleague.com>
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Sean Kerr <sean@code-box.org>
* @author Sergei Miami <miami@blackcrystal.net>
* @version SVN: $Id$
*/
class mySessionStorage extends sfSessionStorage
{
public function initialize($options = array())
{
// add 'regenerate' option, that is true by default in symfony
$options = array_merge(array(
'regenerate' => true,
), $options);
// initialize the parent
parent::initialize($options);
}
public function regenerate($destroy = false)
{
if ( (bool) $this->options['regenerate'] === true)
{
return parent::regenerate($destroy);
}
}
}
Теперь в файле factories.yml заменяем в секции storage название класса на mySessionStorage и добавляем параметр regenerate: false.
storage:
class: mySessionStorage
param:
session_name: symfony
session_cookie_lifetime: 1800
regenerate: false
Можно очистить кэш: symfony cc, и вперёд - делать аутентификацию без этой проблемы.
