【发布时间】:2015-03-30 03:31:21
【问题描述】:
如果用户在 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 服务修复了 VM 上的日期/时间,现在日期就好了:
[root@webvm var]# date
Sun Feb 1 18:35:17 VET 2015
但 5 分钟后(函数调用执行了 5 次)会话仍然存在。这就是我从 Javascript 端调用函数 isLoggedInAction() 的方式:
$.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 小时)保持不变,并惊讶它从未关闭会话。如下图所示,看看页面做了多少请求,看看会话如何仍然存在,为什么?
每 10.5 分钟进行一次 Ajax 调用
$.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
在服务器上的时间很好:
[root@webvm sencamer.dev]# date
Mon Feb 2 07:26:53 VET 2015
我还应该检查什么?
测试 5
好的,我还在做测试,因为这不是一个好的行为。所以,这就是我为这个测试所做的:
- 打开应用程序并开始使用它
- 在某个时刻停止工作并离开应用程序进行 Ajax 调用以检查会话是否仍然存在。 (会话仍然存在,见下图)
- 第一次通话后,我继续处理应用程序,如 图 2 所示,但意外会话结束并且应用程序关闭。
为什么?是什么导致了这种行为?根据我的参数是正确的吗?
这张图片显示了对函数的第一次也是唯一一次调用
通话后我继续工作,但会话关闭
【问题讨论】:
-
您是否在 php 脚本的顶部添加了 session_start() ?更新 yml 文件后,您是否重新启动了 Apache 服务器?
-
@HalayemAnis
session_start()?在这里适用吗?我不这么认为,因为 Symfony 做了这项工作,也许我弄错了,但我现在理解的是 -
注意你的 gc_probability 和 gc_divisor。你有两个,这意味着垃圾收集器(GC)进程在每次会话初始化时启动的概率是 gc_probability / gc_divisor = 1/1 = 1。
-
@acontell 我没关注你,有什么问题?
-
@ReynierPM ,愚蠢的,愚蠢的我。 ... :^ ) 但我找到了解决方案。这很容易。不要指定
cookie_lifetime。第一次访问后,您得到的 cookie 过期时间不再更新。