CodeIgniter会话问题:logout()函数失效,退出后浏览器前后退仍可访问页面
问题描述
我参考了相关CodeIgniter会话实现方案,编写了如下用户控制器代码:
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class User extends CI_Controller { public function __construct() { parent::__construct(); $this->load->helper(array('form', 'url')); $this->load->model('user_model'); $this->load->library('session'); } // 登录逻辑已跑通 public function action_login() { $user_email = $this->input->post('user_email'); $user_password = $this->input->post('user_password'); $wheredatasession = array( 'user_email' => $user_email, 'user_password' => md5($user_password) ); $cek = $this->user_model->ceklogintolong($wheredatasession)->num_rows(); if ($cek > 0) { $data_session = array( 'nama' => $user_email, 'status' => "login" ); $this->session->set_userdata($data_session); redirect('User/homeinfouser'); } else { echo "账号或密码错误"; } } // 登录后跳转的个人主页 public function homeinfouser() { $hasil['print'] = $this->user_model->getinfo(); $this->load->view('templates/sbadmin/header'); $this->load->view('templates/sbadmin/sidebar'); $this->load->view('templates/dashboard/page_informasi', $hasil); $this->load->view('templates/sbadmin/footer'); } // 登出逻辑 public function logout() { $this->session->sess_destroy(); redirect('Landing', 'refresh'); } }
我已经实现了登出方法,调用$this->session->sess_destroy()销毁会话并重定向到首页,但点击Chrome浏览器的后退、前进导航按钮时,仍然可以打开此前已访问过的登录后页面。
问题原因
- 受保护的页面(如
homeinfouser)没有添加登录状态校验逻辑,即使会话已销毁,也没有权限拦截规则 - 浏览器默认会缓存已加载的页面,点击前进后退时直接读取本地缓存,不会向后端发送请求,后端的会话校验逻辑根本不会被触发
解决方案
1. 添加统一的登录状态校验
修改控制器的构造方法,对所有受保护的接口做权限拦截,非登录状态直接跳回首页:
public function __construct() { parent::__construct(); $this->load->helper(array('form', 'url')); $this->load->model('user_model'); $this->load->library('session'); // 新增:非登录状态访问受保护方法时直接跳转 if ($this->session->userdata('status') != 'login' && !in_array($this->router->fetch_method(), ['action_login', 'logout'])) { redirect('Landing'); } }
2. 禁止浏览器缓存受保护页面
给所有需要登录才能访问的页面发送禁止缓存的HTTP头,强制浏览器每次访问都向后端发送请求,触发后端的会话校验逻辑:
可以统一加在构造方法里,也可以单独加在受保护的方法开头:
// 强制禁用页面缓存 $this->output->set_header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); $this->output->set_header('Pragma: no-cache');
补充优化
当前用md5加密密码的方式安全性不足,建议替换为CodeIgniter原生支持的password_hash、password_verify方法处理用户密码。
内容的提问来源于stack exchange,提问作者Heri Prastio
相关产品推荐
相关产品推荐

