• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
CodeIgniter lose session whatever the config

#1
[eluser]Matt L.[/eluser]
Hi everyone,

I'm developing a website using CodeIgniter 1.7.2, its built-in session system and a lot of AJAX request via JQuery.
On this website, users can login thru a modal form. The request is encrypted with JCryption then transmitted to the server using a POST request. If the credentials are valid, the server return a JSON formatted answer then the page is refreshed.
So far so good.

While navigating on the pages, the session seems to disappear randomly, and the Session class throw the following error "A session cookie was not found".
I thought that was caused by an AJAX call (actually the forum responding form dynamically loads a WYSIWYG script and users' posts are sent thru AJAX). So i applied the hack i found on this forum to prevent the session to be updated. Fruitlessly.

I don't understand some points :
- When the user check "stay connected", the session could be lost at a time but he's still connected when the forum's form display "Anonymous" (so weird).
- I logged the whole steps in both session & cookie class but nothing looks wrong (the session is always valid, the cookie isn't deleted, no hacking attempt...). (Could come from the db?)
- I set session storage in the db and the cookie encrypted. I tried all the other conf (without db, with db but no encryption, ...) but nothing works better.

Here is my session & cookies conf :
Code:
$config['sess_cookie_name']    = 'mdsession';
$config['sess_expiration']        = 0;
$config['sess_encrypt_cookie']    = TRUE;
$config['sess_use_database']    = TRUE;
$config['sess_table_name']        = 'sessions';
$config['sess_match_ip']        = FALSE;
$config['sess_match_useragent']    = TRUE;
$config['sess_time_to_update']     = 300;

$config['cookie_prefix']    = "";
$config['cookie_domain']    = 'md.local';
$config['cookie_path']        = "/";

The following script is the used for the connexion:
Code:
function connexion() {
       //Part truncated containing the JCryption stuff

    $query = $this->users_handler->validate_user($user_login_infos, $user_pswd_infos); //Return true if the login & pswd match (and other security check)

        if($query) // if the user's credentials validated...
            {
                $data = array(
                    'is_logged_in' => true,
                    'id' => $query[0]->id,
                    'uid' => $query[0]->uid,
                    'login' => $query[0]->login
                );
                $this->session->set_userdata($data);

            //Setup the output for client-side
                $data['ajax'] = array(
                            's' => 1,
                            'p' => $username
                    );
                $this->load->view('ajax_rtn',$data);

                if($this->input->post('ckbx') == 'on') //Stay connected... ?
                    {
                        $this->load->helper('string');
                        $key = strtolower(random_string('alnum', 32));

                        //Register the key in the db
                        if($this->users_handler->please_remember_me($key))
                            {
                                $cookie_connexion_data = array('i' => $this->session->userdata('id'),
                                                                   'k' => $key);

                                $this->load->library('encrypt');

                                $cookie_connexion_data = serialize($cookie_connexion_data);
                                $cookie_connexion_data = $this->encrypt->encode($cookie_connexion_data);

                                setcookie('remember_me', $cookie_connexion_data, time()+31556926, '/'); //31556926 secondes = 1an                    
                            }
                    }
            }
        else // incorrect username or password
            {
                        //Blabla...
            }
    }

And the code of the main class handling the user option "remember me" and the site structure:
Code:
class md_core {

    function md_structure($data = array())
        {
            $CI =& get_instance();

            //Some of the template stuff on the previous lines | Cookie remember me :
            if(get_cookie('remember_me') && ($CI->session->userdata('is_logged_in') == FALSE))
                {
                    $CI->load->library('encrypt');

                    $cookie_connexion_data = unserialize($CI->encrypt->decode(get_cookie('remember_me')));

                    $query = $CI->Users_Handler->get_all_user_infos($cookie_connexion_data['i']); //If the user exists

                    if(($CI->Users_Handler->do_u_remember_me($cookie_connexion_data)) && ($query)) //...and the key to.
                        {
                            //Enregistrement de la session
                            $data = array(
                                'is_logged_in' => true,
                                'id' => $query[0]->id,
                                'uid' => $query[0]->uid,
                                'login' => $query[0]->login
                            );
                            $CI->session->set_userdata($data);
                        }
                    else
                        {
                            delete_cookie('remember_me');    //Delete cookie
                        }
                }

            //Create the page
            if ($CI->session->userdata('is_logged_in') == TRUE)
                {
                    //Menu for members & admins                    
                }
            else
                {
                    //For visitors
                }
            //Template rendering
        }
}

The PHP version is 5.2.13 and i tested both on windows, mac (dev) and linux (prod) and the same stuff happening each time.
Do you see anything wrong?

Many thanks in advance,

Matt

#2
[eluser]Narkboy[/eluser]
No - I don't see a glaring problem.

Try this - set $config['sess_time_to_update'] to something huge. Then test again. If it works properly, then your issue is the AJAX forcing the session ID to be regenerated without telling the browser. The hack you applied works for CI 2 AFAIK. If it's still broken, then, um...

Smile

/B

#3
[eluser]Matt L.[/eluser]
OK so i changed the sess_time_to_update to a huge value as you'd suggested me. It's only works proprely on pages doesn't containing any AJAX calls.
I've tried to comment the sess_update function but the same issue appears. There's something i don't get.

The hack was this one : http://ellislab.com/forums/viewthread/94915/P15/#760641.

I saw a huge number of developers having the same issue with AJAX & CI. Do you have any idea to definitely fix this issue?

Matt

#4
[eluser]Narkboy[/eluser]
Short answer? No - nothing guaranteed with 1.7.x

I use v2 which is AJAX aware in any case. Honestly, this is rarely an issue for me as I try use AJAX sparingly; it's an addition rather than the basis.

Basically, you need to stop AJAX calls from updating the session, or you must also set the sess_time_to_update to a large enough value that the user will have changed actual page before it regens.

Sorry I can't give you more help!

/B

#5
[eluser]WanWizard[/eluser]
It might be handy to use the search.

Losing sessions when using ajax has been discussed numerous times, and solutions have been provided.

#6
[eluser]Matt L.[/eluser]
@WanWizard : i did a lot of searches about this issue and applied many fix which never worked.
However, i think i solved my problem : actually the XSS filter was failing when parsing the value of the cookie and returned an empty string.

Thank you for your help,

Matt


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


Users browsing this thread:
1 Guest(s)


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2019 MyBB Group.