使用Zend_Session :: rememberMe持久登录

apo*_*rat 11 php zend-framework

我正在使用Zend_Session管理我的用户会话,我希望在我的应用程序中实现"记住我"选项,以保持用户登录2周左右.

我注意到Zend_Session已经有一个内置函数调用Zend_Session::rememberMe,但我不确定该函数逻辑是否正确用作持久登录.

从本质上讲,rememberMe函数只是延长了活动会话的到期日期,这意味着如果用户使用remember me选项,他将使用活动会话保持登录状态2周.

这带来了两个主要问题.

  1. 我将会话存储在数据库中,这意味着所有这些非活动用户都在我的会话表中存储了2周.我有超过50k非活动会话,这会损害应用程序性能.
  2. 我想知道用户是否在24小时不活动后回到该网站,并重新验证他的信息.由于他的会话仍然开放,我无法确定他是否在1小时或1周后回来,因为他有相同的活动会话ID.

我已经读过,如果我想实现一个记住我的功能,我不应该使用会话cookie,我应该创建另一个"登录cookie"来记住一个哈希的user_id和一个令牌.这里是完整的解释:为网站实现"记住我"的最佳方式是什么?

那么为什么zend框架提供这样的功能呢?如果使用它可以创建性能和安全问题?

dre*_*010 10

人们只能推测他们提供这个功能的原因,但我也没有看到任何主要原因.大量的编程语言为您提供了做坏事的工具或编写具有看不见的负面影响的代码.

当然,如果有人任意将其设置为非常大的值,可能会出现无法预料的影响,但需要注意的是,无论在cookie上设置的时间如何,会话数据仍然基于session.gc_maxlifetime进行垃圾收集rememberMe.调用Zend_Session::rememberMe()对该数据的垃圾收集没有影响.

考虑以下:

bootstrap.php中

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();
}
Run Code Online (Sandbox Code Playgroud)

IndexController.php

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您要访问IndexController,第一次看到Setting time.然后,如果您要等待超过45秒,您将看到打印出来的时间和(在我的情况下)下一个请求会话过期.会话数据从服务器中删除,虽然我仍然有以前的cookie,但服务器不再识别它.

我希望如果您在会话保存处理程序中实现垃圾收集回调,那么您仍应该看到从您的数据库中删除旧会话数据,具体取决于您gc_maxlifetime设置的内容.

谈谈你的2个问题:

至于你的第一个问题,我会质疑为什么有50,000个非活动会话会损害性能.如果数据库在会话ID上正确编入索引,即使数据库中有数百万个会话,获取会话数据也应该非常快.你有可能遇到硬件限制吗?正确完成后从50,000条记录中选择数据应该没什么开销.

关于你的第二个问题,我同意迈克,你应该存储一个会话值,说明上次访问的时间,这样,当你开始会话时,你可以查看他们的上次访问,看看自上一页以来已经有多长时间了视图.然后根据您的阈值,您可以确定他们是否在处于非活动状态后返回您的网站.

出于安全原因,如果您发现自上次访问已经过了很长时间,这是重新呼叫的好时机rememberMe(),因为这样做会发出新的cookie并帮助防止会话劫持和固定.


Mik*_*ell 3

+1 注意到 Zend 的“记住我”功能方法背后的主要缺陷。有些人不明白,无论会话处理程序是基于文件还是基于数据库,当他们尝试延长会话生命周期时都会受到惩罚。允许过时的会话持续超过合理的时间范围是一个较弱的解决方案,您最好实施您提供的链接概述的自定义 cookie 解决方案。

直接回答您的问题;谁知道。也许他们没有考虑到许多用户选择数据库会话处理这一事实,并且认为在文件系统上堆积过时的会话 cookie 对性能没有直接影响。

此外,如果您想跟踪用户是否返回并重新建立过时的会话,您可以在会话跟踪表中添加“updated_at”列。那么你就会有两个时间戳列;created_at 和updated_at,这将帮助您做出此决定。