Welcome Guest, Not a member yet? Register   Sign In
Dynamically set configuration on session expire doesn't work
#1

[eluser]Usman -Halal IT[/eluser]
Hi,
I have created an authentication library which uses CodeIgniter's session class. By default the session cookie remains alive for 7200 seconds as set on config.php but I want to increase it to 30 days if users check Remember Me in login form.

Code:
if($this->input->post('remember'))
{
    $this->config->set_item('sess_expiration', '2592000');
}

It sets successfully but it expires very soon. Please give me any suggestions.

Thanks,
Usman.
#2

[eluser]WanWizard[/eluser]
You will have to do that before the session library is loaded, since it reads the config in the constructor, and copies it to internal variables. So modifying it after the fact is pointless.
#3

[eluser]Usman -Halal IT[/eluser]
Thanks, You are right. My session library is auto loaded.
Can please show me way to reload or unload session library.
I tried loading again
$this->CI->load->library('session');
before creating a session in my authentication class but it doesn't work.
#4

[eluser]WanWizard[/eluser]
Libraries in CI are only loaded (and initialized) once.

Options are to do this somewhere before the session library get's loaded (auto or otherwise), or extend the session library and add your code to the MY_Session constructor.
#5

[eluser]Usman -Halal IT[/eluser]
Thanks Again.
I did it in config file.
#6

[eluser]nlogachev[/eluser]
I needed to do the same thing, and figured out how while still keeping the Session library in the autoload.php config.

Two parts to this.

1: Overload the Session Library. What the following code does is it adds an extra check for the 'new_expiration' key in the custom userdata. Apart from that and moving the sess_expiration check to the bottom, it is the same as the built-in function.

Note: I used the database for sessions, but I assume this shouldn't make a difference...



Code:
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Session extends CI_Session
{

    function MY_Session($params=array())
    {
        parent::CI_Session($params);
    }
    
    /**
     * Fetch the current session data if it exists
     *
     * @access    public
     * @return    bool
     */
    function sess_read()
    {
        // Fetch the cookie
        $session = $this->CI->input->cookie($this->sess_cookie_name);

        // No cookie?  Goodbye cruel world!...
        if ($session === FALSE)
        {
            log_message('debug', 'A session cookie was not found.');
            return FALSE;
        }

        // Decrypt the cookie data
        if ($this->sess_encrypt_cookie == TRUE)
        {
            $session = $this->CI->encrypt->decode($session);
        }
        else
        {
            // encryption was not used, so we need to check the md5 hash
            $hash     = substr($session, strlen($session)-32); // get last 32 chars
            $session = substr($session, 0, strlen($session)-32);

            // Does the md5 hash match?  This is to prevent manipulation of session data in userspace
            if ($hash !==  md5($session.$this->encryption_key))
            {
                log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
                $this->sess_destroy();
                return FALSE;
            }
        }

        // Unserialize the session array
        $session = $this->_unserialize($session);

        // Is the session data we unserialized an array with the correct format?
        if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))
        {
            $this->sess_destroy();
            return FALSE;
        }

        // Does the IP Match?
        if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())
        {
            $this->sess_destroy();
            return FALSE;
        }

        // Does the User Agent Match?
        if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50)))
        {
            $this->sess_destroy();
            return FALSE;
        }

        // Is there a corresponding session in the DB?
        if ($this->sess_use_database === TRUE)
        {
            $this->CI->db->where('session_id', $session['session_id']);

            if ($this->sess_match_ip == TRUE)
            {
                $this->CI->db->where('ip_address', $session['ip_address']);
            }

            if ($this->sess_match_useragent == TRUE)
            {
                $this->CI->db->where('user_agent', $session['user_agent']);
            }

            $query = $this->CI->db->get($this->sess_table_name);

            // No result?  Kill it!
            if ($query->num_rows() == 0)
            {
                $this->sess_destroy();
                return FALSE;
            }

            // Is there custom data?  If so, add it to the main session array
            $row = $query->row();
            if (isset($row->user_data) AND $row->user_data != '')
            {
                $custom_data = $this->_unserialize($row->user_data);

                if (is_array($custom_data))
                {
                    foreach ($custom_data as $key => $val)
                    {
                        $session[$key] = $val;
                    }
                }
            }
        }
        
        /**
         * ADDED TO ALLOW CUSTOM EXPIRATION DATES
         */
        if ( isset($session['new_expiration']) )
        {
            $this->sess_expiration = $session['new_expiration'];
        }

        /**
         * MOVED THIS DOWN HERE TO ENABLE THIS NEW FEATURE
         */
        // Is the session current?
        if (($session['last_activity'] + $this->sess_expiration) < $this->now)
        {
            $this->sess_destroy();
            return FALSE;
        }

        /**
         * END NEW
         */

        // Session is valid!
        $this->userdata = $session;
        unset($session);

        return TRUE;
    }

}

?&gt;


Step 2:

In your login logic you need to add the following wherever appropriate (e.g., after checking that the keep_logged_in variable is 1, true, or whatever from the POST data...



Code:
$this->session->set_userdata('new_expiration',1209600); //2 weeks
$this->session->sess_update(); //force the session to update the cookie and/or database



Hope this helps! Smile
#7

[eluser]Usman -Halal IT[/eluser]
Hi,

I have not tried it yet, but anyway thanks for the post.
#8

[eluser]Unknown[/eluser]
[quote author="nlogachev" date="1277319393"]I needed to do the same thing, and figured out how while still keeping the Session library in the autoload.php config.

Two parts to this.

1: Overload the Session Library. What the following code does is it adds an extra check for the 'new_expiration' key in the custom userdata. Apart from that and moving the sess_expiration check to the bottom, it is the same as the built-in function.

Note: I used the database for sessions, but I assume this shouldn't make a difference...



Code:
&lt;?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Session extends CI_Session
{

    function MY_Session($params=array())
    {
        parent::CI_Session($params);
    }
    
    /**
     * Fetch the current session data if it exists
     *
     * @access    public
     * @return    bool
     */
    function sess_read()
    {
        // Fetch the cookie
        $session = $this->CI->input->cookie($this->sess_cookie_name);

        // No cookie?  Goodbye cruel world!...
        if ($session === FALSE)
        {
            log_message('debug', 'A session cookie was not found.');
            return FALSE;
        }

        // Decrypt the cookie data
        if ($this->sess_encrypt_cookie == TRUE)
        {
            $session = $this->CI->encrypt->decode($session);
        }
        else
        {
            // encryption was not used, so we need to check the md5 hash
            $hash     = substr($session, strlen($session)-32); // get last 32 chars
            $session = substr($session, 0, strlen($session)-32);

            // Does the md5 hash match?  This is to prevent manipulation of session data in userspace
            if ($hash !==  md5($session.$this->encryption_key))
            {
                log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
                $this->sess_destroy();
                return FALSE;
            }
        }

        // Unserialize the session array
        $session = $this->_unserialize($session);

        // Is the session data we unserialized an array with the correct format?
        if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))
        {
            $this->sess_destroy();
            return FALSE;
        }

        // Does the IP Match?
        if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())
        {
            $this->sess_destroy();
            return FALSE;
        }

        // Does the User Agent Match?
        if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50)))
        {
            $this->sess_destroy();
            return FALSE;
        }

        // Is there a corresponding session in the DB?
        if ($this->sess_use_database === TRUE)
        {
            $this->CI->db->where('session_id', $session['session_id']);

            if ($this->sess_match_ip == TRUE)
            {
                $this->CI->db->where('ip_address', $session['ip_address']);
            }

            if ($this->sess_match_useragent == TRUE)
            {
                $this->CI->db->where('user_agent', $session['user_agent']);
            }

            $query = $this->CI->db->get($this->sess_table_name);

            // No result?  Kill it!
            if ($query->num_rows() == 0)
            {
                $this->sess_destroy();
                return FALSE;
            }

            // Is there custom data?  If so, add it to the main session array
            $row = $query->row();
            if (isset($row->user_data) AND $row->user_data != '')
            {
                $custom_data = $this->_unserialize($row->user_data);

                if (is_array($custom_data))
                {
                    foreach ($custom_data as $key => $val)
                    {
                        $session[$key] = $val;
                    }
                }
            }
        }
        
        /**
         * ADDED TO ALLOW CUSTOM EXPIRATION DATES
         */
        if ( isset($session['new_expiration']) )
        {
            $this->sess_expiration = $session['new_expiration'];
        }

        /**
         * MOVED THIS DOWN HERE TO ENABLE THIS NEW FEATURE
         */
        // Is the session current?
        if (($session['last_activity'] + $this->sess_expiration) < $this->now)
        {
            $this->sess_destroy();
            return FALSE;
        }

        /**
         * END NEW
         */

        // Session is valid!
        $this->userdata = $session;
        unset($session);

        return TRUE;
    }

}

?&gt;


Step 2:

In your login logic you need to add the following wherever appropriate (e.g., after checking that the keep_logged_in variable is 1, true, or whatever from the POST data...



Code:
$this->session->set_userdata('new_expiration',1209600); //2 weeks
$this->session->sess_update(); //force the session to update the cookie and/or database



Hope this helps! Smile[/quote]

Great post,Thank u very much!!Resolve my problem. :lol:
#9

[eluser]Unknown[/eluser]
[quote author="mochitto" date="1326178848"]Why so much code?
Code:
if(!$remeber)
{
   $this->session->sess_expire_on_close = TRUE;
}
else
{
   $this->session->sess_expiration = 60*60*24*31;
   $this->session->sess_expire_on_close = FALSE;
}
  
  $this->session->set_userdata(array('user_id' => 456));
Looks working too..[/quote]

..I tested this solution and works fine for me too. Thanks mochitto. :-)
#10

[eluser]Unknown[/eluser]
if($this->input->post('rememberme') == 'on')
{
$this->session->sess_expire_on_close = FALSE;
}
else
{
$this->session->sess_expire_on_close = TRUE;
}

mochitto can u check what is wrong in my code. I want to destroy the session when the rememberme is not on when users close the browser. The session is not destroy even the rememberme is off. Please help me wat is wrong Smile




Theme © iAndrew 2016 - Forum software by © MyBB