【问题标题】:Remove session from ci_sessions table on logout注销时从 ci_sessions 表中删除会话
【发布时间】:2018-02-11 11:24:13
【问题描述】:

我已经实现了 Codeigniters 购物车类,它自动启用会话(我从文档中收集的内容)并将会话数据存储到数据库中的 ci_sessions 表中。

但是,当我以用户身份注销时,会话仍保留在数据库中。如果重新登录,旧会话将保留并创建新会话。它是否正确?登录时,我从来没有真正检查 ci_sessions 表中的现有会话,这是我需要实现的东西还是 codeigniter 自动处理的东西?

这是我的登录和注销功能,我取消了会话变量,但这本身并不会从数据库中删除会话。

class User extends CI_Controller {

  function __construct() {
    parent::__construct(); // Don't forget to call the parent constructor in this method

  }

  public function dashboard() {
    $this->load->view('template/header');
    $this->load->view('user/dashboard');
    $this->load->view('template/footer');
  }

  public function index()
    {
            $this->load->view('template/header');
            $this->load->view('landing_page');
            $this->load->view('template/footer');
    }

    public function register() {
        $this->load->view('template/header');
        $this->load->view('user/register');
        $this->load->view('template/footer');
    }

    public function login() {
        $this->load->view('template/header');
        $this->load->view('user/login');
        $this->load->view('template/footer');
    }

  public function registerUser() {
    //form validation rules
    $this->form_validation->set_error_delimiters('<div class="error" style="color: red;">', '</div>');
    $this->form_validation->set_rules('first_name', 'First Name', 'required');
    $this->form_validation->set_rules('last_name', 'Last Name', 'required');
    $this->form_validation->set_rules('dob', 'Date of Birth ', 'required');
    $this->form_validation->set_rules('address_1', 'Address One', 'required');
    $this->form_validation->set_rules('address_2', 'Address Two', 'required');
    $this->form_validation->set_rules('postcode', 'Postcode', 'required');
    $this->form_validation->set_rules('city', 'City', 'required');
    $this->form_validation->set_rules('county', 'County', 'required');
    $this->form_validation->set_rules('email', 'Email', 'required');
    $this->form_validation->set_rules('password1', 'Password One', 'required');
    $this->form_validation->set_rules('passwordagain', 'Password Confirmation', 'required|matches[password1]');

    if($this->form_validation->run() == FALSE) {
      //if form validation fails, send user back and display errors
      $this->register();
    } else {
      //prepare data for insert to db
      $data = array(
        'first_name' => $this->input->post('first_name'),
        'last_name' => $this->input->post('last_name'),
        'date_of_birth' => $this->input->post('dob'),
        'address_1' => $this->input->post('address_1'),
        'address_2' => $this->input->post('address_2'),
        'postcode' => $this->input->post('postcode'),
        'city' => $this->input->post('city'),
        'county' => $this->input->post('county'),
        'email' => $this->input->post('email'),
        'password' => $this->hashPassword($this->input->post('password1'))
      );

      $this->User_model->insertUser($data);
      redirect('user/index');
    }
  }

  public function loginUser() {
    $this->form_validation->set_error_delimiters('<div class="error" style="color: red;">', '</div>');
    $this->form_validation->set_rules('email', 'Email', 'required');
    $this->form_validation->set_rules('password', 'password', 'required');

    if($this->form_validation->run() == FALSE) {
      $this->login();
    } else {
      $email = $this->input->post('email');
      $password = $this->hashPassword($this->input->post('password'));

      $user_id = $this->User_model->login($email, $password);

      if($user_id) {
        $user_data = array(
          'user_id' => $user_id,
          'email' => $email,
          'logged_in' => true
        );

        $this->session->set_userdata($user_data);

        redirect('user/dashboard');
      } else {
        redirect('user/login');
      }
    }
  }

  // Log user out
  public function logout(){
    // Unset user data
    $this->session->unset_userdata('logged_in');
    $this->session->unset_userdata('user_id');
    $this->session->unset_userdata('email');

    // Set message
    $this->session->set_flashdata('user_loggedout', 'You are now logged out');
    $this->session->sess_destroy();

    redirect('user/login');

  }

  function hashPassword($password) {
       return md5($password);
   }
}

配置.php

$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'applicationcookie';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;

在上面添加了我的 config.php。我使用数据库作为会话驱动程序。

【问题讨论】:

    标签: php mysql codeigniter session


    【解决方案1】:

    您在login controller 中错误地设置了session。这就是session 保留的原因。

    我假设您已经在application/config/autoload.php 下自动加载了会话。

    你创建的数组是正确的。

    $user_data = array(
              'user_id' => $user_id,
              'email' => $email,
              'logged_in' => true
           );
    

    接下来将其设置为会话如下。

    $this-&gt;session-&gt;set_userdata('login_session',$user_data); //这里你搞错了。

    设置会话后,将用户重定向到仪表板或主页。

    log out用户,使用以下代码

    if($this->session->userdata('login_session'){
        $this->session->unset_userdata('login_session');
    
        // Set message
        $this->session->set_flashdata('user_loggedout', 'You are now logged out');
        redirect('user/login');
    }else{
        redirect('user/login');
    }
    

    现在每次用户打开您的网站时,检查用户的登录会话是否处于活动状态。

    在构造函数下添加此代码。

    class Dashboard extends CI_Controller{
    
       public function __construct(){
          parent::__construct();
          if(!($this->session->userdata('login_session'))){
             redirect('user/login','refresh');
          }
     }
    

    同样,在您的登录控制器中,检查登录会话是否处于活动状态。

    class Login extends CI_Controller{
        public function __construct() {
            parent::__construct();
            if($this->session->userdata('login_session')){
                redirect('user/dashboard','refresh');
            }
        }
    }
    

    编辑 - 如果您在一个控制器中同时拥有这两种方法,则使用此代码

    class User extends CI_Controller{
         public function __construct() {
              parent::__construct();
              if(!$this->session->userdata('login_session')){
                  redirect('login','refresh');
              }
          }
    
          public function login(){
              $this->load->view('login_view');
          }
    
          public function dashboard(){
              //since in controller I'm checking the session, you need not have to check it in the dashboard.
              $this->load->view('dashboard_view');
          }
     }
    

    希望对你有帮助。

    【讨论】:

    • 感谢帮助,我是不是在用户验证登录后不设置会话?另外,我没有用于登录、仪表板等的单独控制器。它们只是我的用户控制器中的方法,我如何每次都检查与我的代码相关的会话?
    • 您在注销用户时设置了会话,但并未取消设置。所以你有这个问题。如果您没有单独的控制器,则在函数级别使用条件。
    • 您上面的建议仍然不起作用。即使在使用您的代码单击注销后,数据库中的会话仍然存在。这可能是因为我的用户控制器是主控制器吗?
    • 为什么要将会话存储在数据库中。任何特定的原因。默认情况下,Codeigniter 会明智地处理会话。
    • 对不起,兄弟。我犯了一个错误。我又修改了答案。
    【解决方案2】:

    当他们点击注销时,将他们发送到destroys the session 的控制器/方法。

    $this->session->sess_destroy();
    

    这会使会话无效并阻止您进一步访问它。 CodeIgniter 会自行清理数据库中过期的会话,不需要进行垃圾回收。

    【讨论】:

    • 销毁会话将导致销毁所有用户会话。我认为你不应该向任何人建议这个。
    • 你错了。会话销毁仅在调用时销毁当前会话。这在我链接到的文档中有清楚的解释。
    猜你喜欢
    • 1970-01-01
    • 2019-03-16
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    • 2015-05-02
    相关资源
    最近更新 更多