用户
 找回密码
 入住 CI 中国社区
搜索
查看: 4093|回复: 3
收起左侧

[会话/Cookie] CI 数据库SESSION失效问题的解决方法

[复制链接]
发表于 2013-11-1 20:40:15 | 显示全部楼层 |阅读模式
本帖最后由 lunux2008 于 2013-11-1 20:40 编辑

1.首先这不是一个常见问题,传统刷页面的方式不会遇到
2.同一时间只有一个AJAX请求的时候也不会遇到
3.同一时间有两个或两个以上AJAX请求必然遇到

配置文件:
$config['sess_expiration']  = 30;             //设置session的有效期是30秒
$config['sess_time_to_update']   = 5;   //session更新间隔是5秒

遇到的问题是:
每隔2秒钟,同时发起2个AJAX请求控制器的两个不同ACTION,每当到5秒钟 更新SESSION的时候,SESSION就失效了。

---------------------------------------------------------------
    function sess_update()
    {
        if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
        {
            return;
        }
        $old_sessid = $this->userdata['session_id'];
        $new_sessid = '';
        while (strlen($new_sessid) < 32)
        {
            $new_sessid .= mt_rand(0, mt_getrandmax());
        }
        $new_sessid .= $this->CI->input->ip_address();
        $new_sessid = md5(uniqid($new_sessid, TRUE));

        $this->userdata['session_id'] = $new_sessid;
        $this->userdata['last_activity'] = $this->now;
        $cookie_data = NULL;

        if ($this->sess_use_database === TRUE)
        {
            $cookie_data = array();
            foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
            {
                $cookie_data[$val] = $this->userdata[$val];
            }

            $this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
        }

        $this->_set_cookie($cookie_data);
    }

--------------------------------------------------------------

看了一下 session.php 文件的代码,在update() 方法里最后这句,它会用新生成的session_id 替换原来的session_id,在数据库里会替换,同时把新的session_id放到cookie发到客户端,期望的是客户端下次用session_id来请求。但是如果是同时发出了两个AJAX请求,那么第一个到达的AJAX请求会执行到修改库里的SESSION_ID这里,新的SESSION_ID会写到客户端,但是第二个到达的AJAX还是在用老的SESSION_ID来访问,这个时候 用老的SESSION_ID到库里查数据当然结果是空的,然后会给第二个到达的AJAX请求创建一个新的空的SESSION,并又给客户端发出一个了更新的SESSION_ID。这一轮结束之后,SESSION就失效了。

解决的办法是
1.$this->userdata['session_id'] = $new_sessid;   这句注释掉。
2.            $this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
变成
$this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now), array('session_id' => $old_sessid)));

就是不让原来的session_id 被修改,永远使用原来的session_id, 只延长 last_activity 上次访问时间





发表于 2014-5-4 17:25:01 | 显示全部楼层
用原生session的飘过 。。
发表于 2015-12-9 17:28:13 | 显示全部楼层
呵呵,都是逼的呀。。。

本版积分规则