0
votes

I have implemented Codeigniters cart class which automatically enables sessions (what I gather from documentation) and stores the session data into my ci_sessions table in the db.

However, when I logout as a user, the session remains in the db. If log back in, the old session remains and new one is created. Is this correct? On login, I'm never really checking the ci_sessions table for an existing session, is this something I need to implement or is it something codeigniter handles automatically?

Here is my function for logging in and logging out, I unset the session variables but this in itself doesn't remove the session from the db.

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);
   }
}

Config.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;

Added my config.php above. I'm using the database as the session driver.

2

2 Answers

0
votes

You have wrongly set the session in your login controller. That's why the session is remaining.

I assume you have autoloaded the session under the application/config/autoload.php.

The array what you have created is correct.

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

Next set it to the session as follows.

$this->session->set_userdata('login_session',$user_data); //Here you made mistake.

Once the session is set, redirect the user to dashboard or homepage.

To log out the user, use below code

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');
}

Now every time when the user opens your website, check if the user's login session is active.

Under constructor add this code.

class Dashboard extends CI_Controller{

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

Similarly, in your login controller, check if the login session is active.

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

Edit - If you have both the methods in a single controller then use this code

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');
      }
 }

Hope this can help you.

0
votes

When they click logout, send them to a controller/method that destroys the session.

$this->session->sess_destroy();

This should invalidate the session and prevent you from accessing it further. CodeIgniter will clean up expired sessions in the db on it's own, you do not need to do garbage collection.