You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter3会话过期后用户无法重新登录问题求助

CodeIgniter3 会话过期后无法重新登录的修复方案

问题根源

会话过期后,users表中存储的session_id未被清理或验证有效性。用户重新登录时,系统检测到数据库中的旧session_id与当前新生成的session_id不一致,误判为账号在其他设备登录。

具体修复步骤

1. 验证存储的session_id是否有效

修改M_Auth模型的get_user_session_id方法,先检查该session_id在ci_sessions表中是否存在且未过期:

public function get_user_session_id($email)
{
    $this->db->where('email', $email);
    $user = $this->db->get($this->_table)->row();
    if (!$user || !$user->session_id) {
        return NULL;
    }

    // 验证session_id是否有效(未过期)
    $expire_time = time() - $this->config->item('sess_expiration');
    $this->db->where('id', $user->session_id);
    $this->db->where('timestamp >', $expire_time);
    $valid_session = $this->db->get('ci_sessions')->row();

    return $valid_session ? $user->session_id : NULL;
}

2. 自动清理过期会话对应的用户session_id

通过CodeIgniter钩子实现会话过期时,自动清空users表中关联的session_id:

配置钩子(application/config/hooks.php)

$hook['post_system'][] = [
    'class'    => 'SessionCleanup',
    'function' => 'expire_user_sessions',
    'filename' => 'SessionCleanup.php',
    'filepath' => 'hooks'
];

创建钩子类(application/hooks/SessionCleanup.php)

class SessionCleanup
{
    public function expire_user_sessions()
    {
        $CI =& get_instance();
        $CI->load->database();

        // 获取所有已过期的session记录
        $expire_time = time() - $CI->config->item('sess_expiration');
        $CI->db->where('timestamp <', $expire_time);
        $expired_sessions = $CI->db->get('ci_sessions')->result();

        if (!empty($expired_sessions)) {
            $expired_ids = array_column($expired_sessions, 'id');
            // 清空对应用户的session_id
            $CI->db->where_in('session_id', $expired_ids);
            $CI->db->update('users', ['session_id' => NULL]);
        }
    }
}

3. 优化登录状态检查逻辑

修改M_Auth模型的check_login_status方法,确保当前会话与用户存储的session_id一致,且会话未过期:

public function check_login_status()
{
    $user_id = $this->session->userdata('user_id');
    $current_session_id = session_id();
    
    if (!$user_id) {
        return FALSE;
    }
    
    $user = $this->db->get_where($this->_table, ['id' => $user_id])->row();
    
    // 会话ID不匹配,直接销毁当前会话
    if (!$user || $user->session_id != $current_session_id) {
        $this->session->sess_destroy();
        return FALSE;
    }

    // 验证当前会话是否未过期
    $expire_time = time() - $this->config->item('sess_expiration');
    $this->db->where('id', $current_session_id);
    $this->db->where('timestamp >', $expire_time);
    $valid_session = $this->db->get('ci_sessions')->row();

    if (!$valid_session) {
        $this->session->sess_destroy();
        $this->db->where('id', $user_id)->update($this->_table, ['session_id' => NULL]);
        return FALSE;
    }
    
    return TRUE;
}

4. 登录时强制覆盖旧session_id

原登录逻辑中已包含更新session_id的代码,只要登录成功,就会将users表中的session_id替换为当前新的session_id,这部分无需额外修改。

内容的提问来源于stack exchange,提问作者Muhammad Ashraf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 16:37:54