我正在使用Zend_Session
来管理我的用户会话,我希望在我的应用程序中实现“记住我”选项,以保持用户登录2周左右。
我注意到Zend_Session
已经有一个名为Zend_Session::rememberMe
的内置函数,但是我不确定该函数逻辑是否可以用作持久登录。
本质上,rememberMe函数只是延长了活动会话的到期日期,这意味着如果用户使用remember me选项,他将使用活动会话保持登录状态2周。
这引出了两个主要问题。
我已经读过,如果我想实现一个记住我的功能,我不应该使用会话cookie,我应该创建另一个“登录cookie”来记住一个哈希的user_id和一个令牌。这是完整的解释:What is the best way to implement "remember me" for a website?
那么为什么zend框架提供这样的功能呢?如果使用它会产生性能和安全问题?
答案 0 :(得分:10)
人们只能推测他们提供这个功能的原因,但我也没有看到任何主要原因。大量的编程语言为您提供了做坏事的工具或编写具有看不见的负面影响的代码。
当然,如果有人任意将其设置为非常大的值,可能会出现无法预料的影响,但需要注意的是,会话数据仍然受基于session.gc_maxlifetime的垃圾收集的影响,无论{ {1}}在Cookie上设置的时间。调用rememberMe
对该数据的垃圾回收没有影响。
请考虑以下事项:
Zend_Session::rememberMe()
protected function __initSession() {
ini_set('session.gc_maxlifetime', 45); // set session max lifetime to 45 seconds
ini_set('session.gc_divisor', 1); // 100% chance of running GC
Zend_Session::start();
}
如果您要访问public function indexAction() {
$data = new Zend_Session_Namespace('data');
if (!isset($data->time)) {
// no active session - set cookie lifetime and set some data
Zend_Session::rememberMe(90*86400); // 90 days
$data->time = time();
echo "Setting time";
} else {
echo date('r', $data->time);
}
}
,则第一次看到IndexController
。然后,如果您要等待超过45秒,您将看到打印出来的时间和(在我的情况下)下一个请求会话过期。会话数据从服务器中删除,虽然我仍然有以前的cookie,但服务器不再识别它。
我希望如果您在会话保存处理程序中实现垃圾回收回调,那么您仍应该看到从您的数据库中删除旧的会话数据,具体取决于您Setting time
的设置。
至于你的第一个问题,我会质疑为什么有50,000个非活动会话会影响性能。如果数据库在会话ID上正确编入索引,即使数据库中有数百万个会话,获取会话数据也应该非常快。你有可能遇到硬件限制吗?正确完成后从50,000条记录中选择数据应该没什么开销。
关于你的第二个问题,我同意迈克,你应该存储一个会话值,说明上次访问的时间,这样,当你开始会话时,你可以查看他们的上一次访问,看看自上次访问以来已经过了多长时间他们的最后一页视图。然后根据您的阈值,您可以确定他们是否在处于非活动状态后返回您的网站。
出于安全原因,如果您发现自上次访问已经过了很长时间,那么现在是重新调用gc_maxlifetime
的好时机,因为这样做会发出新的Cookie并帮助阻止会话劫持和录制
答案 1 :(得分:3)
+1注意到Zend采用“记住我”功能的方法背后的主要缺陷。有些人不理解当他们尝试延长会话生命周期时会有一个惩罚,无论会话处理程序是基于文件还是基于数据库。允许陈旧的会话持续超过合理的时间范围是一个弱的解决方案,您最好实现您提供的链接概述的自定义cookie解决方案。
直接回答你的问题;谁知道。也许他们没有考虑到许多用户选择数据库会话处理这一事实,并认为在文件系统上堆积陈旧的会话cookie对性能没有直接影响。
此外,如果您想跟踪用户是否回来并重新建立陈旧会话,您可以在会话跟踪表中添加“updated_at”列。那么你将有两个时间戳列; created_at和updated_at,这将有助于您做出此决定。