Codeigniter session data lost after redirect

2019-01-24 16:13发布

问题:

I am using codeigniter 2.1.0.

I am trying to do a register/login function using the session library in the codeigniter.

The register/login with the session library worked fine for localhost, but when I put it live and tried it, the session does not work.

My controller login works this way. I check the credentials, once ok I set my session data and redirect to another page.

$user_data = array(
                   'username'       => $result->user_name,
                   'email'          => $result->user_email,
                   'userid'         => $result->user_id,
                   'role'           => $result->user_role,
                   'login_state'    => TRUE,
                   'lastlogin'      => time(),
               );

$this->session->set_userdata($user_data);           
print_r( $this->session->all_userdata());            
redirect(base_url('dashboard'));

at this point here when I print all my session data, they do print out. But at the dashboard controller side, when i attempt to print the session data out, they were not there anymore.

Any idea why? Thanks in advance for the help.

回答1:

I'm not sure what exactly is the problem. Recently I faced this too..

It was working before in my development running php7.0.

Currently it is only working in my production server running nginx and php 5.6. My development server seems to be not working and keeps on regenerate new row in sessions table. My development server is using php7.1, on homestead virtualbox development environment, usually being used for Laravel projects.

I managed to get over this by taking this step.

1) Go to system/libraries/Session/Session.php

2) Comment session_start() by adding //. We want to relocate the sessionn_start().

3) Go down to line 315 where it says Security is king, and comment out until line 351

4) Then go to your main index.php ( the root index.php )

5) Add session_start() at the top once.

6) Okay try again. Hopefully it works. My guess is that it is not working with php 7.1 and some update need to be done in this Session.php file.

  1. My CI Version is 3.1.1



回答2:

if you are working in CI 3.x and just upgraded your server php version to php 7.x

Go to system/libraries/Session/session.php at Line no 281 and replace ini_set('session.name', $params['cookie_name']); by ini_set('session.id', $params['cookie_name']);



回答3:

This is an addition to "edelweiss" answer but I feel like it require more attention and hence posting as answer.

CI 2.1 is infamous to have session related problems. It is better we replace the built-in Sessions.php file with the one below.

The link given by "edelweiss" is broken. The Session.php file he mentions is:

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
//>  makes dw cs4 happy
/**
* Session class using native PHP session features and hardened against session fixation.
*
* @package     CodeIgniter
* @subpackage  Libraries
* @category    Sessions
* @author      Dariusz Debowczyk, Matthew Toledo
* @link        http://www.philsbury.co.uk/index.php/blog/code-igniter-sessions/
*/
class CI_Session {
    var $flashdata_key     = 'flash'; // prefix for "flash" variables (eg. flash:new:message)
    function CI_Session()
    {
        $this->object =& get_instance();
        log_message('debug', "Native_session Class Initialized");
        $this->_sess_run();
    }
    /**
    * Regenerates session id
    */
    function regenerate_id()
    {
        // copy old session data, including its id
        $old_session_id = session_id();
        $old_session_data = $_SESSION;
        // regenerate session id and store it
        session_regenerate_id();
        $new_session_id = session_id();
        // switch to the old session and destroy its storage
        session_id($old_session_id);
        session_destroy();
        // switch back to the new session id and send the cookie
        session_id($new_session_id);
        session_start();
        // restore the old session data into the new session
        $_SESSION = $old_session_data;
        // update the session creation time
        $_SESSION['regenerated'] = time();
        // session_write_close() patch based on this thread
        // http://www.codeigniter.com/forums/viewthread/1624/
        // there is a question mark ?? as to side affects
        // end the current session and store session data.
        session_write_close();
    }
    /**
    * Destroys the session and erases session storage
    */
    function destroy()
    {
        unset($_SESSION);
        if ( isset( $_COOKIE[session_name()] ) )
        {
            setcookie(session_name(), '', time()-42000, '/');
        }
        session_destroy();
    }
    /**
    * Alias for destroy(), makes 1.7.2 happy.
    */
    function sess_destroy()
    {
        $this->destroy();
    }
    /**
    * Reads given session attribute value
    */
    function userdata($item)
    {
        if($item == 'session_id'){ //added for backward-compatibility
            return session_id();
        }else{
            return ( ! isset($_SESSION[$item])) ? false : $_SESSION[$item];
        }
    }
    /**
    * Sets session attributes to the given values
    */
    function set_userdata($newdata = array(), $newval = '')
    {
        if (is_string($newdata))
        {
            $newdata = array($newdata => $newval);
        }
        if (count($newdata) > 0)
        {
            foreach ($newdata as $key => $val)
            {
                $_SESSION[$key] = $val;
            }
        }
    }
    /**
    * Erases given session attributes
    */
    function unset_userdata($newdata = array())
    {
        if (is_string($newdata))
        {
            $newdata = array($newdata => '');
        }
        if (count($newdata) > 0)
        {
            foreach ($newdata as $key => $val)
            {
                unset($_SESSION[$key]);
            }
        }
    }
    /**
    * Starts up the session system for current request
    */
    function _sess_run()
    {
        session_start();
        $session_id_ttl = $this->object->config->item('sess_expiration');
        if (is_numeric($session_id_ttl))
        {
            if ($session_id_ttl > 0)
            {
                $this->session_id_ttl = $this->object->config->item('sess_expiration');
            }
            else
            {
                $this->session_id_ttl = (60*60*24*365*2);
            }
        }
        // check if session id needs regeneration
        if ( $this->_session_id_expired() )
        {
            // regenerate session id (session data stays the
            // same, but old session storage is destroyed)
            $this->regenerate_id();
        }
        // delete old flashdata (from last request)
        $this->_flashdata_sweep();
        // mark all new flashdata as old (data will be deleted before next request)
        $this->_flashdata_mark();
    }
    /**
    * Checks if session has expired
    */
    function _session_id_expired()
    {
        if ( !isset( $_SESSION['regenerated'] ) )
        {
            $_SESSION['regenerated'] = time();
            return false;
        }
        $expiry_time = time() - $this->session_id_ttl;
        if ( $_SESSION['regenerated'] <=  $expiry_time )
        {
            return true;
        }
        return false;
    }
    /**
    * Sets "flash" data which will be available only in next request (then it will
    * be deleted from session). You can use it to implement "Save succeeded" messages
    * after redirect.
    */
    function set_flashdata($newdata = array(), $newval = '')
    {
        if (is_string($newdata))
        {
            $newdata = array($newdata => $newval);
        }
        if (count($newdata) > 0)
        {
            foreach ($newdata as $key => $val)
            {
                $flashdata_key = $this->flashdata_key.':new:'.$key;
                $this->set_userdata($flashdata_key, $val);
            }
        }
    }
    /**
    * Keeps existing "flash" data available to next request.
    */
    function keep_flashdata($key)
    {
        $old_flashdata_key = $this->flashdata_key.':old:'.$key;
        $value = $this->userdata($old_flashdata_key);
        $new_flashdata_key = $this->flashdata_key.':new:'.$key;
        $this->set_userdata($new_flashdata_key, $value);
    }
    /**
    * Returns "flash" data for the given key.
    */
    function flashdata($key)
    {
        $flashdata_key = $this->flashdata_key.':old:'.$key;
        return $this->userdata($flashdata_key);
    }
    /**
    * PRIVATE: Internal method - marks "flash" session attributes as 'old'
    */
    function _flashdata_mark()
    {
        foreach ($_SESSION as $name => $value)
        {
            $parts = explode(':new:', $name);
            if (is_array($parts) && count($parts) == 2)
            {
                $new_name = $this->flashdata_key.':old:'.$parts[1];
                $this->set_userdata($new_name, $value);
                $this->unset_userdata($name);
            }
        }
    }
    /**
    * PRIVATE: Internal method - removes "flash" session marked as 'old'
    */
    function _flashdata_sweep()
    {
        foreach ($_SESSION as $name => $value)
        {
            $parts = explode(':old:', $name);
            if (is_array($parts) && count($parts) == 2 && $parts[0] == $this->flashdata_key)
            {
                $this->unset_userdata($name);
            }
        }
    }
}


回答4:

Maybe you not automatic load library session.

Have you try this in controller dashboard:

$this->load->library('session');
print_r($this->session->all_userdata());


回答5:

PHP 7 Upgrade - * Known SESSION / COOKIE Bug

This answer addresses the known session/cookie bug - when you upgrade to PHP7 from PHP 5.

If your CodeIgniter version is @ 3.1.0 or below - and you are upgrading to PHP 7.1 - You will need to update CodeIgniter.

There is a bug with $this->session->set_userdata(); - that can be pretty annoying. It will overwrite your session as soon as you redirect or visit another page within your site structure.


Some other discussions about the bug: https://github.com/bcit-ci/CodeIgniter/issues/4830

*Save some time and see post by See post "dyanakiev commented on Oct 23, 2016" -

"Just to confirm: Everything works perfect with 3.1.1, no more problems with sessions.