我希望我的会话在30分钟的不活动后过期,但是当我设置这个时,我的用户随机注销,即使他们可能只有几秒钟的不活动。我认为问题在于重新生成会话ID。
我的理解是,为了获得预期的效果,我需要在会话中将memor_me_seconds配置为1800。然后在我的引导中,在调用$sessionMgr->start()
之后,我需要调用$sessionMgr->rememberMe()
。
rememberMe()
呼叫regenerateId()
,我认为这就是问题所在。我认为,如果浏览器快速连续发出两个请求,则处理第一个请求,并在服务器上更新会话id。当服务器接收到第二个请求时,它仍然携带旧的会话id,该会话id不再被识别,因此服务器将您视为已注销。这听起来可能吗?我认为它必须是,因为我可以通过直接调用regenerateId()
(而不是调用rememberMe()
)来模拟问题
那么,问题是我应该如何实现我想要的解决方案?就会话超时而言,我可以在会话中存储"最后访问"时间,并在收到请求时将其与当前时间进行比较。但这将使rememberMe()
功能冗余。至于重新生成id以避免会话固定,我不知道如何有效地做到这一点。总是会有多个浏览器请求快速连续出现的情况,所以服务器可能会不同步…
对于会话超时,您可以执行以下操作。我在每个控制器扩展的类中都有这个这个超时方法在每个请求上运行。此外,超时值是在登录时初始设置的。
/**
* If user is inactive for 5 minutes, log them out.
*
* @return void | ZendMvcControllerPluginRedirect
*/
protected function timeout()
{
// User Active so reset time session. (5minutes)
// Note: (I'm using $this->identity which is basically an Auth object)
// but would work the same way as $_SESSION['timeout']
if ($this->identity->timeout + 300 > time())
{
$this->identity->timeout = time();
}
// session timed out, logout user
// this routes to the location of destroying the session, etc.
else
{
return $this->redirect()->toRoute('logout', array());
}
}
另外,如果您想要自动注销用户而不需要刷新页面,那么您可能希望使用AJAX在(n)秒后检查超时值以进行重置。
防止会话固定:我还没有在《ZF2》中实现它。然而,我在ZF1中做了,它工作得很好,没有问题。我知道这真的不能给你一个答案,但我认为沿着同样的路线也会在ZF2中工作。
随机注销:我在一些应用程序中看到,这是通过更改php.ini文件中的一些会话属性来修复的。在另一个应用程序中,我目前使用ZF2的rememberMe($time)
没有问题。
了解如何设置会话存储选项和初始化会话命名空间对象可能也会有所帮助。在ZendSessionContainer
中,注意doc块读:
/**
* Session storage container
*
* Allows for interacting with session storage in isolated containers, which
* may have their own expiries, or even expiries per key in the container.
* Additionally, expiries may be absolute TTLs or measured in "hops", which
* are based on how many times the key or container were accessed.
*/
所以像这样:
$this->session = new SessionContainer($this->namespace, $manager);
和设置memorme:
$this->session->getManager()->rememberMe($time);
希望这能给你指明正确的方向。
好的,所以我从错误的角度来看待这个问题。我假定"记住我"one_answers"cookie生存期"是为了帮助处理会话超时而设计的。这个问题清楚地表明,如何在30分钟后使PHP会话过期?,我应该实现我自己的解决方案。
此外,在阅读本文http://phpsec.org/projects/guide/4.html之后,我可以看到,我只需要在用户登录或退出时重新生成会话ID。