codeigniter3开启sess_match_ip后用户频繁掉登录,因动态ip或nat导致remote_addr变动,而该配置会严格校验ip不一致即废弃session;需配合sess_encrypt_cookie、正确配置proxy_ips及https/httponly等防护措施。

CodeIgniter3开启sess_match_ip后为什么用户频繁掉登录
因为动态IP或NAT网关导致$_SERVER['REMOTE_ADDR']每次请求都变化,而sess_match_ip = TRUE会严格比对IP,不一致就废弃当前session。常见于校园网、4G/5G移动网络、某些企业宽带出口,甚至部分云WAF(如Cloudflare)透传IP失败时也会触发。
实操建议:
- 上线前先确认真实客户端IP是否稳定——用
var_dump($_SERVER['REMOTE_ADDR'])在多个页面连续刷几次看是否变动 - 若使用CDN或反向代理(如Nginx+Cloudflare),必须在Web服务器层把真实IP写入
$_SERVER['HTTP_X_FORWARDED_FOR']或$_SERVER['HTTP_X_REAL_IP'],再在CI3的application/config/config.php中补全:$config['proxy_ips'] = '104.28.0.0/16, 104.27.128.0/20, 172.64.0.0/13'; // Cloudflare IP段示例
- 不要在开发环境盲目开启——本地localhost和测试机IP固定,但上线后行为完全不同
配置sess_match_ip的正确位置和依赖项
必须同时设置sess_match_ip = TRUE和sess_encrypt_cookie = TRUE,否则攻击者可篡改cookie中的IP字段绕过校验。仅开前者等于形同虚设。
修改application/config/config.php中的session相关配置:
$config['sess_driver'] = 'files'; $config['sess_cookie_name'] = 'ci_session'; $config['sess_expiration'] = 7200; $config['sess_save_path'] = APPPATH . 'cache/session/'; $config['sess_match_ip'] = TRUE; $config['sess_encrypt_cookie'] = TRUE; $config['sess_use_database'] = FALSE;
注意:sess_encrypt_cookie依赖PHP的mcrypt(CI3.1.11前)或openssl(CI3.1.12+),若报错Unable to load the session encryption library,需检查对应扩展是否启用。
为什么登录后必须调用$this->session->regenerate()
不调用会导致会话固定(Session Fixation):攻击者提前诱导用户访问带固定ci_session cookie的链接(如?ci_session=abc123),用户登录后仍沿用该ID,攻击者即可直接复用。
正确写法只在登录成功且写入用户数据前执行一次:
if ($this->auth_model->login($username, $password)) {
$this->session->regenerate(); // 必须放在最前面
$this->session->set_userdata('user_id', $user_id);
redirect('dashboard');
}
容易踩的坑:
- 在登录控制器构造函数里调用——此时用户还没认证,反而破坏正常流程
- 用
$this->session->sess_destroy()代替——它只清空数据,不换ID,旧session文件仍有效 - 忘记配合
sess_time_to_update(默认300秒)——长时间页面停留后自动更新ID可能引发并发冲突
IP绑定不是银弹,得搭配其他防护才真正有效
单靠sess_match_ip无法防住所有劫持场景:比如用户在同一局域网换设备、手机在WiFi和蜂窝网间切换、或代理出口IP池轮转。它只是增加攻击成本,不能替代基础防护链。
必须同步落实的三项:
- 强制HTTPS下传输cookie:
ini_set('session.cookie_secure', '1')+$config['cookie_secure'] = TRUE(否则ci_session明文走HTTP) - 禁止JS读取cookie:
$config['cookie_httponly'] = TRUE(防XSS窃取) - 关闭URL传递session ID:
ini_set('session.use_trans_sid', '0')(防止?ci_session=xxx泄露到Referer或日志)
这些配置不在CI3框架内,得在PHP启动阶段(如index.php头部或Web服务器配置)手动加,晚于session_start()就无效。











