CodeIgniter中AJAX传值设置Session失效及登出异常问题求助
解决CodeIgniter中AJAX登录后Session设置异常及登出问题
问题根源分析
从你的代码来看,核心问题出在Session的设置逻辑和登出判断逻辑上,还有登录时的合法性验证顺序也有问题:
- Session嵌套存储错误:你把用户数据嵌套在了
ci_session这个键下,但CodeIgniter的Session应该直接将用户数据作为顶层键存储,这会导致后续读取、删除Session时找不到正确的数据。 - 登出判断逻辑错误:
$this->session->unset_userdata()的返回值不能用来判断删除是否成功,而且你删除的是自己错误嵌套的键,不是真正的用户Session数据。 - 登录验证顺序颠倒:当前代码不管用户是否验证成功,就直接设置Session,这会导致即使用户名密码错误,Session也被错误设置。
分步修正方案
1. 修正登录控制器的Session设置逻辑
先验证用户合法性,再设置正确的Session结构:
public function check_login() { $username = $this->input->post('username'); $password = $this->input->post('password'); // 先调用模型验证用户是否合法 $details = $this->user_model->check_username($username, $password); // 只有验证通过时才设置Session if (!empty($details)) { // 直接将用户数据存入Session顶层,无需嵌套 $newdata = array( 'username' => $username, 'is_logged_in' => true // 新增登录状态标识,方便后续判断登录状态 ); $this->session->set_userdata($newdata); } echo json_encode($details); }
2. 优化AJAX登录的判断逻辑
原代码用obj.length判断可能失效(如果模型返回的是对象而非数组),改为判断返回数据是否非空,同时去掉阻塞浏览器的同步请求:
$(function() { $('#login').click(function() { var username = $("#username").val(); var password = $("#password").val(); $.ajax({ url:"<?php echo base_url();?>home/check_login", type:"POST", data:{username:username,password:password}, success:function(data) { var obj = JSON.parse(data); // 根据返回数据的长度判断是否登录成功 if (obj && Object.keys(obj).length > 0) { window.location.href = "<?php echo base_url();?>home/show_dashboard"; } else { $('#modal_warning').modal('show'); } } }); }); });
3. 修正登出控制器的逻辑
CodeIgniter的unset_userdata需要指定正确的Session键,或者直接销毁整个Session,同时用跳转替代直接加载视图:
public function log_out() { // 方式1:删除指定的用户Session键 $this->session->unset_userdata(array('username', 'is_logged_in')); // 方式2:如果不需要保留其他Session数据,可销毁整个Session // $this->session->sess_destroy(); // 用redirect跳转登录页,符合MVC流程 redirect('home/login'); }
4. 验证Session是否正确设置
可以在任意控制器方法中添加以下代码,查看Session存储结构:
echo '<pre>'; print_r($this->session->userdata()); echo '</pre>';
正常情况下,你应该能看到username和is_logged_in作为顶层键存在,而非嵌套在ci_session中。
额外注意事项
- 确保已在
config/autoload.php中自动加载Session库:$autoload['libraries'] = array('session'); - 检查
config/config.php中的Session驱动配置,若使用files驱动,需确保存储路径可写;若用database驱动,需提前创建Session表。 - 模型中的
check_username方法要做密码哈希验证(禁止明文存储密码),示例:
public function check_username($username, $password) { $this->db->where('username', $username); $query = $this->db->get('users'); if ($query->num_rows() == 1) { $user = $query->row(); // 验证哈希密码 if (password_verify($password, $user->password)) { return $user; } } return array(); // 验证失败返回空数组 }
内容的提问来源于stack exchange,提问作者akku
相关产品推荐
相关产品推荐

