Login sessions data and can we delete session from db in code igniter

时间:2016-04-25 09:19:26

标签: codeigniter session codeigniter-3

I made login app using codeigniter 3.0.1, i'm facing couple of problems. First is things are not working when i don't check the 'remember me' check box and it still logs the user in when i close the browser and open it again with direct link "localhost/ci_login_app/index.php/account" seems like

$config['sess_expire_on_close'] = TRUE;

have no effect on it :/

i have configured config.php like this

$config['sess_driver'] = 'database';
#$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 60*60*24*7;

$config['sess_expire_on_close'] = TRUE;

$config['sess_match_useragent'] = FALSE;

$config['sess_time_to_update'] = 300;

$config['sess_save_path'] = 'ci_sessions';

#$config['sess_use_database'] = TRUE;

$config['sess_match_ip'] = FALSE;
$config['sess_regenerate_destroy'] = TRUE;

This is my authentication file uesr_authentication.php

<?php

Class User_Authentication extends CI_Controller 
{

public function __construct() 
{
    parent::__construct();
}

// Show login page
public function index() 
{
    $this->load->view('layouts/header');
    $this->load->view('login_form');
    $this->load->view('layouts/footer');
}

public function user_login_process() 
{   

    $session_set_value = $this->session->all_userdata();

    // Check for remember_me data in retrieved session data
    if (isset($session_set_value['remember_me']) && $session_set_value['remember_me'] == "1") 
    {
        redirect('account');
    }       // Check for validation

    else{

        $this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean');
        $this->form_validation->set_rules('password', 'Password', 'trim|required|xss_clean');

        if ($this->form_validation->run() == FALSE) 
        {
            $this->load->view('layouts/header');
            $this->load->view('login_form');
            $this->load->view('layouts/footer');
        } 

        else 
        {
                $result = $this->model_login->login_user();

                switch ($result) 
                {
                    case 'authenticated':
                    redirect('account');

                        break;
                    case 'incorrect_password':
                        echo "Error loging in, password not correct...!";
                        $this->load->view('layouts/header');
                        $this->load->view('login_form');
                        $this->load->view('layouts/footer'); 

                        break;

                    case 'not_activated':
                        echo "Please activate your account before logging in...!";
                        $this->load->view('layouts/header');
                        $this->load->view('login_form');
                        $this->load->view('layouts/footer'); 

                        break;

                    case 'incorrect_username':
                        echo "Error loging in, password/username not correct...!";
                        $this->load->view('layouts/header');
                        $this->load->view('login_form');
                        $this->load->view('layouts/footer'); 

                        break;

                    default:
                        echo "Enter correct value, press backspace";
                        break;
                }
            }
        }

}

// Logout from admin page
public function logout() 
{

// Destroy session data
    $this->session->sess_destroy();
    $data['message_display'] = 'Successfully Logout';
    redirect('account');        
}
}
?>

This is my login.php controller

<?php
class Login extends CI_Controller
{
public function __construct()
{
    parent::__construct();
}

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

public function login_user()
{
    $this->form_validation->set_rules('username', 'User Name', 'trim|required');
    $this->form_validation->set_rules('password', 'Password ','trim|required');

    if($this->form_validation->run() === FALSE)
    {
        echo "Validations doesn't run correctly!<br>";
        $this->load->view('layouts/header');
        $this->load->view('login_form');
        $this->load->view('layouts/footer');       
    }
    else
    {
        $result = $this->model_login->login_user();

        switch ($result) {
            case 'logged_in':
                redirect('home');
                // $this->load->view('admin_page');


                break;
            case 'incorrect_password':
                echo "Error loging in, password not correct...!";
                $this->load->view('layouts/header');
                $this->load->view('login_form');
                $this->load->view('layouts/footer'); 

                break;

            case 'not_activated':
                echo "Please activate your account before logging in...!";
                $this->load->view('layouts/header');
                $this->load->view('login_form');
                $this->load->view('layouts/footer'); 

                break;

            case 'incorrect_username':
                echo "Error loging in, password/username not correct...!";
                $this->load->view('layouts/header');
                $this->load->view('login_form');
                $this->load->view('layouts/footer'); 

                break;

            default:
                # code...
                break;
        }
    }
}


public function reset_password()
{
    if (isset($_POST['email'])) 
    {
        # code...
        $this->form_validation->set_rules('email','Email Address','trim|required|valid_email');

        if ($this->form_validation->run() === FALSE) {
            # code...
            $this->load->view('layouts/header');
            $this->load->view('login/view_reset_password', array('error' => 'Please provide a valid email address'));
            $this->load->view('layouts/footer');
        }
        else
        {
            $email = trim($this->input->post('email'));
            $result = $this->model_login->email_exists($email);

            if ($result) 
            {
                $this->send_reset_password_email($email, $result);
                $this->load->view('layouts/header');
                $this->load->view('login/view_reset_password_sent', array('email' => $email));
                $this->load->view('layouts/footer');

            }
            else
            {

                $this->load->view('layouts/header');
                $this->load->view('login/view_login_reset_password_sent', array('error' => 'Email not registerd here'));
                $this->load->view('layouts/footer');
            }
        }
    }
    else
    {

        $this->load->view('layouts/header');
        $this->load->view('login/view_reset_password');
        $this->load->view('layouts/footer');
    }

}

public function reset_password_form($email, $email_code)
{
    if (isset($email) && isset($email_code)) 
    {
        #$email = trim($email);
        $email_hash = sha1($email.$email_code);
        $verified = $this->model_login->verify_reset_password_code($email, $email_code);

        if ($verified) 
        {
            $this->load->view('layouts/header');
            $this->load->view('login/view_update_password', 
                array(
                'email_hash'=>$email_hash,
                'email_code'=>$email_code,
                'email' => $email
                ));
            $this->load->view('layouts/footer');
        }
        else
        {
            echo "Can't get verified";
        }
    }
}

public function send_reset_password_email($email, $name)
{
    $this->load->library('email');
    $email_code = md5($this->config->item('salt').$name);

    $this->email->set_mailtype('html');
    $this->email->from($this->config->item('bot_email'),'reset password email');
    $this->email->to($email);
    $this->email->subject('Please reset your password');

    $message = "<!DOCTYPE html><html>
    <head>
        <title>Reset Password</title>
    </head>
    <body>";
    $message .= "<p> Dear '{$name}'</p>";
    $message .='<p> we want to help you reset your password! please <strong> <a href="'.base_url().'index.php/login/reset_password_form/'.$email.'/'.$email_code.'">Click here </a> </strong> to reset your password</p>';
    $message .="<p>Thank you</p>";
    $message .="</body></html>";

    $this->email->message($message);
    $this->email->send();
}

public function update_password()
{
    print_r($_REQUEST);
    $email = $this->input->post('email');
    $email_hash = $this->input->post('email_hash');
    $email_code = sha1($this->input->post('email').$this->input->post('email_code'));



    if (!isset($email,$email_hash) || ($email_hash != $email_code)) 
    {
        # code...
        die("Error updating password, unauthorize access");
    }

    $this->form_validation->set_rules('email_hash', 'Email Hash', 'trim|required');
    $this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
    $this->form_validation->set_rules('new-password', 'password', 'trim|required|matches[new-password-again]');
    $this->form_validation->set_rules('new-password-again', 'password', 'trim|required');

    if ($this->form_validation->run() === FALSE) 
    {
        $this->load->view('layouts/header');
        $this->load->view('login/view_update_password');
        $this->load->view('layouts/footer');
    }
    else
    {
        $result = $this->model_login->update_password();

        if ($result) 
        {
            $this->load->view('layouts/header');
            $this->load->view('login/view_update_password_success');
            $this->load->view('layouts/footer');
        }

        else
        {
            $this->load->view('layouts/header');
            $this->load->view('login/view_update_password',array(
                'error' => 'problem updating your password please contact site admin xyz@abc.com' ));
            $this->load->view('layouts/footer');
        }
    }
}
}
?>

This is my model class model_login.php

<?php
class Model_login extends CI_Model
{

public function __construct()
{
    # code...
    parent::__construct();
}

public function login_user()
{
    $username = $this->input->post('username');
    #$password = $this->input->post('password');

    $remember = $this->input->post('remember_me');

    $userpass = sha1($this->config->item('salt').$this->input->post('password'));

    $sql = "SELECT * FROM users WHERE username = '{$username}'  LIMIT 1";
    $result = $this->db->query($sql);
    $row = $result->row();

    if($result->num_rows() == 1)
    {
        if($row->activated)
        {

            if ($row->password == $userpass) 
            {

                if ($remember) 
                {
                    $this->session->set_userdata('remember_me', TRUE);
                    $this->config->set_item('sess_expire_on_close', FALSE);
                }

                $sess_data = array(
                'username' => $username,
                'password' => $userpass
                );
                $this->session->set_userdata('logged_in', $sess_data);

                return 'authenticated';
            }
            else
            {
                return 'incorrect_password';
            }
        }
        else
        {
            return 'not_activated';
        }
    }
    else
    {
        return 'incorrect_username';
    }
}

public function email_exists($email)
{
    $sql = "SELECT name , email FROM users WHERE email = '{$email}' LIMIT 1";
    $result = $this->db->query($sql);
    $row = $result->row();

    return ($result->num_rows() === 1 && $row->email) ? $row->name : false;
}

public function verify_reset_password_code($email, $code)
{
    $sql = "SELECT name, email FROM users WHERE email = '{$email}' LIMIT 1";
    $result = $this->db->query($sql);
    $row = $result->row();

    if ($result->num_rows() === 1) 
    {
        return ($code == md5($this->config->item('salt').$row->name)) ? true : false;
    }
    else
        return false;
}


public function update_password()
{
    $email = $this->input->post('email');
    echo $this->input->post('password')."<br>";
    $password = sha1($this->config->item('salt').$this->input->post('new-password'));

    echo $this->input->post('password')." hashed password <br>";

    $sql = "UPDATE users SET password = '{$password}' WHERE email = '{$email}' LIMIT 1";
    $this->db->query($sql);

    if (isset($sql)) {
            return true;
        }   
        else
        {
            return false;
        }
}

private function set_session($session_data)
{
    $sess_data = array(
        'id' => $session_data['id'],
        'name' => $session_data['name'],
        'username' => $session_data['username'],
        'email' => $session_data['email'],
        'logged_in' => 1 );

    $this->session->set_userdata($sess_data);
}

}
?>

I'm setting session only when user logs in, Second problem is that there are so many records generated from time to time in db when we visiting/revisiting page, how do we handle record in db how do we delete the record when user logs out ? It just unset the data on calling

$this->session->sess_destroy();

i have been searching on it from more than two days, if anyone can help i would be grateful. I had a moment when these setting/code worked spot on but i don't know what happened it all messed up. If any other file is required please tell me. Thanks in advance

1 个答案:

答案 0 :(得分:1)

Garbage Collector

As mentioned in the (old) CodeIgniter docs, CI has his own Garbage Collector. This is still true for CI 3.x

The Session class has built-in garbage collection which clears out expired sessions so you do not need to write your own routine to do it.

As stated in the CI forum, the Garbage Collector uses session.gc_probability and session.gc_divisor values, provided by your php.ini, to invoke the cleanup process. (By default, there is a chance of 1% to clean up the old sessions when making a session request)


Config Values

Anyway, I'd suggest you to set sess_regenerate_destroy to FALSE (according to the newer CI docs)

Whether to destroy session data associated with the old session ID when auto-regenerating the session ID. When set to FALSE, the data will be later deleted by the garbage collector.


Destroy session on tab close

$config['sess_expire_on_close'] is not available anymore in CI 3.x

For detecting the browser or tab close by using JavaScript (but it is slightly unreliable) , take a look on this answer. The easiest way to make a session last until the browser is being closed is to set the session_expiration value to 0.

The number of seconds you would like the session to last. If you would like a non-expiring session (until browser is closed) set the value to zero: 0

Source