Сессия заканчивается, даже если я работаю, время сеанса, Ajax и Symfony2
Я установил приложение для закрытия сеанса по таймауту, если пользователь ничего не делает за 10 минут. В config.yml
у меня есть следующее:
session:
handler_id: ~
cookie_lifetime: 600 # 10 minutes
gc_maxlifetime: 600 # 10 minutes
gc_probability: 1
gc_divisor: 1
Я делаю вызов Ajax каждую минуту, чтобы проверить, будет ли сеанс близок к истечению срока действия или нет, и это то, что я проверяю:
public function isLoggedInAction(Request $request)
{
$response = array();
$response['authenticated'] = FALSE;
$status = 200;
$securityContext = $this->container->get('security.context');
if ($securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
$response['authenticated'] = TRUE;
}
return new JsonResponse($response, $status ?: 200);
}
По какой-то непонятной причине не работает, и каждые 10 минут сеанс закрывается независимо от того, работает ли я со страницей или нет, почему? Я что-то упустил?
Изменить 1 Выполнено новые значения, которые все еще не работают:
session:
handler_id: ~
cookie_lifetime: 1800
gc_maxlifetime: 600
gc_probability: 1
gc_divisor: 100
Пока я работал на странице, выполняя вызовы Ajax и некоторые другие задачи, сеанс был закрыт, поэтому он не работает. Единственное значение, которое, по-видимому, работает для меня до сих пор, установлено cookie_lifetime: 86400 #1 day
, что для меня сумасшедшее!
Изменить 2 После того, как @acontell предложит исправить время и дату VM, я пытаюсь использовать эти новые значения (10 минут занимает слишком много времени, поэтому я изменил 3):
session:
handler_id: ~
cookie_lifetime: 1800
gc_maxlifetime: 180 # session will expire after 3 minutes of inactivity
gc_probability: 1
gc_divisor: 100
И также я установил дату/время на виртуальной машине, включив службу ntpd
, и теперь дата прекрасна:
[[email protected] var]# date
Sun Feb 1 18:35:17 VET 2015
Но через 5 минут (вызов функции был выполнен 5 раз) сессия все еще жива. Вот как я вызываю функцию isLoggedInAction()
со стороны JavaScript:
$.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
if( data.authenticated ){
var timer = window.setInterval(function(){
$.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
if( !data.authenticated ){
window.clearInterval(timer);
$.growl({
message: 'La sesión ha expirado por inactividad, debe <a href=""><b>iniciar seción</b></a> nuevamente.'
}, {
type: "danger",
allow_dismiss: false,
timer: 10000,
animate: {
enter: 'animated fadeInDown',
exit: 'animated fadeOutUp'
},
onHide: function(){
location.reload();
}
});
}
}).fail(function(){});
},60000);
}
}).fail(function(){});
Смотрите изображение ниже:
Тест 3
После того, как все было хорошо работает, я сделал последний и окончательный тест: откройте приложение и оставайтесь нетронутым всю ночь (почти 8 часов) и удивите его, чтобы он никогда не закрывал сессию. Как показано ниже, посмотрите, сколько запросов запрашивает страница, и как сеанс все еще жив, почему?
Вызов Ajax производится каждый раз: 10.5 минут
$.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
if( data.authenticated ){
var timer = window.setInterval(function(){
$.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
if( !data.authenticated ){
window.clearInterval(timer);
$.growl({
message: 'La sesión ha expirado por inactividad, debe <a href=""><b>iniciar seción</b></a> nuevamente.'
}, {
type: "danger",
allow_dismiss: false,
timer: 10000,
animate: {
enter: 'animated fadeInDown',
exit: 'animated fadeOutUp'
},
onHide: function(){
location.reload();
}
});
}
}).fail(function(){});
}, 210000);
}
}).fail(function(){});
Настройки говорят, что сеанс должен быть продлен: 10 минут.
session:
handler_id: ~
cookie_lifetime: 630000
gc_maxlifetime: 630000 # session will expire after 10 minutes of inactivity
gc_probability: 1
gc_divisor: 100
Время на сервере в порядке:
[[email protected] sencamer.dev]# date
Mon Feb 2 07:26:53 VET 2015
Что еще я должен проверить?
Тест 5
Хорошо, я все еще делаю тест, потому что это плохое поведение. Итак, это то, что я сделал для этого теста:
- Откройте приложение и начните работу над ним.
- В какой-то момент перестаньте работать и оставьте приложение сделать вызов Ajax, чтобы проверить, жив ли сеанс или нет. (сеанс еще жив, см. изображение ниже)
- После этого первого вызова я продолжаю работать над приложением, так как изображение 2 показывает, но конец сеанса сюрпризов заканчивается, и приложение закрывается.
Почему? Что вызывает такое поведение? Правильно ли это на основе моих параметров?
Это изображение показывает первый и единственный вызов функции
После того, как звонок был выполнен, я продолжаю работать, но сеанс закрывается
Ответы
Ответ 1
Во-первых, следите за gc_probability
и gc_divisor
. Если оба значения равны единице, это означает, что вероятность запуска процесса сборщика мусора (GC) при каждой инициализации сеанса составляет gc_probability / gc_divisor = 1/1 = 1
(100%).
Вы можете оставить его по умолчанию или присвоить ему большее число, чтобы уменьшить вероятность вызова GC.
Например:
session:
# handler_id set to null will use default session handler from php.ini
handler_id: ~
cookie_lifetime: 600 # Ten minutes
gc_probability: 1
gc_divisor: 10000
Кроме того, если вы используете виртуальную машину, проверьте дату своего сервера, итоговый файл cookie сеанса будет отмечен временем истечения срока действия time() + cookie_lifetime
, где время берется с сервера.
Возможно, что, если у сервера была плохая дата, cookie истечет немедленно. Представьте себе: дата сервера 2015-01-31
, ваш браузер 2015-02-01
. Сервер отправляет cookie, срок действия которого истекает на 2015-01-31
в 11:00, ваш браузер получает файл cookie с уже прошедшей датой истечения срока.
Ответ 2
попробуйте с этими параметрами:
gc_probability: 0
gc_divisor : 1000