【问题标题】:session_set_save_handler() w/ session timeoutsession_set_save_handler() 带会话超时
【发布时间】:2015-06-30 12:26:27
【问题描述】:

我目前有一个包含session_set_saver_handler的类,它工作正常。但是我想实现一个会话超时,这会导致比最初预期的更多的问题。

据我所知,会话生命周期如下;

  • 打开
  • 阅读
  • 关闭

调用session_destroy() 将运行_destroy(),这将运行我设置的配置。

该类直接写入数据库以存储我的会话。该数据库包含以下列;

  • 会话;包含 sessionID
  • 数据;包含会话的数据
  • 更新时间;包含会话的最后一个活动
  • 已锁定;默认为假。但是,如果 $variable $access 设置为 true

所以,目前我有以下内容;

public function _read($id) 
    {

        $timeout = time() - 30;

        $this->database->query('SELECT updatedTime, data FROM sessions WHERE session = :id');
        $this->database->bind(':id', $id); 

        if($this->database->execute())
        {
            if($this->database->rowCount() > 0)
            {
                $row = $this->database->singleResult();

                if($row['updatedTime'] < $timeout)
                {
                    session_unset();
                    session_destroy(); 
                    return; 
                }

                return $row['data']; 
            }
        }

        return '';
    }

public function _destroy($id) 
    {
        $locked = true; 

        $this->database->query('UPDATE sessions SET locked = :locked WHERE session = :id');
        $this->database->bind(':locked', $locked); 
        $this->database->bind(':id', $id); 

        if($this->database->execute())
        {
            return true; 
        } 

        return false;
    }

当条件为真($row['updatedTime'] &lt; $timeout)时,它会运行session_destroy,但是因为它依赖于传递给类的数据库对象,所以当session_destroy 运行时它会被破坏,这意味着没有活动的数据库连接。好吧,据我所知,这是正在发生的事情。我可能完全理解错了。

30 秒超时仅用于测试目的。好的,所以我要的是当会话的最后一个活动超过当前设置的超时时,它需要销毁会话并将locked 列设置为true

谢谢!

【问题讨论】:

    标签: php oop session session-set-save-handler


    【解决方案1】:

    你不需要在那里打电话给session_destroy()。如果会话已过期,只需致电header('Location: logout.php') 或您想要发生的任何其他事情。在您的logout.php 文件中调用session_destroy(); 并重定向到登录页面。

    要在过期会话后进行清理,您需要定义垃圾收集功能(session_set_save_handler 中的第六个参数),您将在其中执行您在销毁功能中为当前会话所做的所有工作,但只选择过期会话。

    此外,我只会删除该会话的记录,而不是将其设置为“锁定” - 你永远不会回到那个会话,对吗?

    另外,在_destroy 函数中,您可以删除会话cookie:

    if(isset($_COOKIE['PHPSESSID'])){
        setcookie("PHPSESSID",$_COOKIE['PHPSESSID'],time() - 100000,"/");
    }
    

    为防止会话固定攻击(用户重复使用相同的会话 ID,或窃取该 ID 并将其放入其会话 cookie),请在用户登录后立即调用 session_regenerate_id(true);

    【讨论】:

    • 最后一点像这样非常危险 - 你应该retrieve the actual cookie name 而不是依赖可配置的默认值。
    • 调用header(...) 效果很好!但是,用户不会因为它实际上没有“销毁”而保持相同的会话吗?据我了解,gc依赖于php.ini配置,是在php.ini中配置的条件下运行的?我想在使用 header() 重定向用户时处理会话关闭。如果这有意义吗?
    • 我更新了答案-您可以在logout.php 中调用session_destroy(); 并重定向到登录页面,这样该会话将以与用户单击logout 按钮时相同的方式被销毁.
    • 太棒了!那很简单,我不敢相信错过了!非常感谢,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    相关资源
    最近更新 更多