Welcome Guest, Not a member yet? Register   Sign In
CI 1.7: session database lose user_data after update
#11

[eluser]Pascal Kriete[/eluser]
It shouldn't make a difference. Using get_instance will give you a reference to the current controller object, so changing one will change the other.

I've attached my test hook if you're interested.

Here's the hook call:
Code:
$hook['post_controller_constructor'] = array(
                                'class'    => 'Authenticate',
                                'function' => 'check_user',
                                'filename' => 'authenticate.php',
                                'filepath' => 'hooks'
                                );

And just for fun: I wrote it so I could set a route like this to mask the login page:
Code:
$route['abc'] = 'backend/login';
#12

[eluser]Unknown[/eluser]
Excuse me for posting in a such old thread, but I'm having the same issues than Giraf. I'm using CI 1.7.1 and I'm losing user_data on session regeneration.

By reviewing on sess_update() I've seen that custom user_data is never copied from old session, so custom variables ('logged_in', for example) get lost on session regeneration.

Is this a bug or am I doing something wrong?
#13

[eluser]Pascal Kriete[/eluser]
Quote:By reviewing on sess_update() I’ve seen that custom user_data is never copied from old session, so custom variables (‘logged_in’, for example) get lost on session regeneration.

It doesn't need to be copied the session id is updated on the existing row. Have you tried it with a very simple piece of code? If so, could post that small snippet, please?

Welcome to CodeIgniter.
#14

[eluser]Steiner[/eluser]
I use a user-defined library in the application directory to do relatively the same thing... but this is for an admin panel... so you can't get into the rest of the site without Username and Pass.

Keep in mind that I'm using the database to store sessions, this is a slight mod of the Admin Panel login script I'm using and it's based of CI's coding standards and PHP5's class constructs.

Feel free to expand upon it.

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

class Authorization
{
    var $CI;
    var $user_table = 'db.users_table';

    function __construct()
    {
        //Get current instance of the CodeIgniter class
        //(Remember without =& it will create a new instance of the class
        //Defeating the purpose of the session class
        $this->CI =& get_instance();

        // If you have this auto-loading via the autoload.php in the libraries section,
        // It will run this check on every page, so you wont have to call it
        // in every controller.
        //
        // This is also set to flashdata the page attempted on the login, so when you
        // pass the login it will bring you to that page.
        if ( ! $this->CI->session->userdata('admin_logged_in') && $this->CI->uri->segment(1) != 'login' )
        {
           $this->CI->session->set_flashdata('refer', current_url());
           redirect('/login/', 'location', 301);
        }


    }

    function login($user = '', $password = '', $remember_me = false)
    {
        //Make sure login info was sent
        if($user == '' OR $password == '')
        {
            return false;
        }

        //Check if already logged in
        if($this->CI->session->userdata('username') == $user)
        {
            //User is already logged in.
            return true;
        }

        //Check against user table
        $this->CI->db->where('username', $user);
        $this->CI->db->where('password', md5($password));
        $query = $this->CI->db->getwhere($this->user_table);

        if ($query->num_rows() > 0)
        {
            $row = $query->row_array();


            //Destroy old session
            $this->CI->session->sess_destroy();


            //Create a fresh, brand new session
            $this->CI->session->sess_create();

            //Remove the password field
            unset($row['password']);

            //Set session data
            $this->CI->session->set_userdata($row);


            //Make sure that our user has the right credentials
            if ( ($row['admin'] + $row['lieutenant'] + $row['moderator']) > 0)
            {
                //Set an extra parameter for the lib to check to speed up authorization
                $this->CI->session->set_userdata(array('admin_logged_in' => true));
            }

            //Login was successful
            return true;
        }
        else
        {
            //No database result found
            return false;
        }

    }
// This is commented because we don't need this if we're using Database to store sessions.
// Uncomment if you wish to store userdata in cookies, be sure to check your config to adhere to this change

/*    function check_cookie($ck = '')
    {
        // need to clean this up later - passing in the value isn't necessary
        $ck = get_cookie('cit_session');


        //Check against user table
        $this->CI->db->where('username', $user);
        $this->CI->db->where('password', md5($password));
        $query = $this->CI->db->getwhere($this->user_table);
         $row = $query->row();

        if ($query->num_rows() > 0)
        {
            //Destroy old session
            $this->CI->session->sess_destroy();

            //Create a fresh, brand new session
            $this->CI->session->sess_create();

            //Remove the password field
            unset($row->password);

            //Set session data
            $this->CI->session->set_userdata($row);

            //Set logged_in to true
            $this->CI->session->set_userdata(array('admin_logged_in' => true));

            //Login was successful
            return true;
        }
        else
        {
            //No database result found
            return false;
        }
    }*/

    function logout()
    {
        //Destroy session
        delete_cookie($this->CI->config->item('cookie_prefix').$this->CI->config->item('sess_cookie_name'));
        $this->CI->session->sess_destroy();
    }
}
#15

[eluser]metalking[/eluser]
Hello ! I have the same error (well, almost the same) on my website.

It is using CI 1.7.1. The strange thing about it is that not all the session informations are lost. The ones that are set by a custom auth library (so via $this->CI->session->set_userdata) are ok, but every other session data is lost when the session_id is updated..
One other strange thing is that these datas are lost only when the array that I put in my session has multiples entries (2+). It doesn't happen with only one entry.

Could this be a clue? When the array that I put in a userdata has one entry, the session updates fine, but when the array has 2 or more entries, these userdatas are lost.

Thanks !
#16

[eluser]metalking[/eluser]
I have done some tests with phpmyadmin open, looking at the session entry after each step, and I have found that the data are lost only when there are too many http queries at the same time.

Explainations :

My website is a platform for vocabulary learning. And I have an exercise module that is in ajax. After each exercise, a method is called that updates the learning level of each word in the database. For some exercices, this is not a problem, because each word comes after another, but for a particular one, all the words are used together. So when I validate the exercise, there is one ajax call for each word, everything at the same time, and the server doesn't know that it is the same session, and creates a new entry in the database. So I should maybe set a timeout for each ajax call, so that the server is not saturated. (no more true, see edit)

One mistery remains : why are one a few datas passed to the new session entry in the database? This is not so important, but just strange.

Bye

EDIT : I managed to have only one ajax query at every step of the exercise process, but there is still this data-loss problem.
So do you have any idea?

Thanks in advance !
#17

[eluser]michaeljdennis[/eluser]
I'm having the same problem. Anyone have any luck?
#18

[eluser]treeface[/eluser]
Same problem here. The session cookie appears to get destroyed when a lot of AJAX calls are made. I wonder if using a native session library will help..
#19

[eluser]WanWizard[/eluser]
Using the search option might help, there have been tons of posts about this subject.

CI standard rotates session id's every 5 minutes. If this happens during an ajax call, the session id is renewed but the cookie isn't updated, which invalidates the session. To fix this, create this helper:
Code:
/**
* is_ajax_call
*
* Determines if the current page request is done through an AJAX call
*
* @access    public
* @param    void
* @return    boolean
*/
if ( ! function_exists('is_ajax_call'))
{
    function is_ajax_call()
    {
        if ( isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == "XMLHttpRequest")
        {
            // we should do more checks here, for now this is it...
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
}

And extend the session library:
Code:
/**
* Session Class Extension
*/
class MY_Session extends CI_Session
{
    /**
     * Do not update an existing session on ajax calls
     *
     * @access    public
     * @return    void
     */
    function sess_update()
    {
                if ( ! is_ajax_call() )
                {
                        parent::sess_update();
                }
        }
}
#20

[eluser]treeface[/eluser]
WanWizard...man..you have no idea how long I've been searching for a solution to this. I've read and re-read every last character in that Session library until my eyes turned...I dunno...blue? But how do you phrase a question about a problem whose source is so nebulous that you're just taking random guesses at which functions might be causing it? It's often difficult to simply ask the right kinds of questions when ignorance is the main obstacle.

All that aside, you might be the most awesome person in the history of history. If this works (at work now..will be testing later tonight), I will be eternally grateful.




Theme © iAndrew 2016 - Forum software by © MyBB