CI 묻고 답하기

제목 IE 세션 공유 문제
글쓴이 onlybell 작성시각 2013/10/17 15:58:03
댓글 : 2 추천 : 0 스크랩 : 0 조회수 : 22309   RSS
도메인에서 로그인시 세션을 생성하고 있습니다.
그런데 문제는 IE에서만 www.xxx.com 에서는 로그인이 안되고,
xxx.com에서는 정상적으로 로그인 및 세션 공유가 되고 있습니다.
IE만 그러네요. IE 버전은 10.0.9200 입니다.

config의 설정은 아래와 같습니다.
$config['sess_cookie_name']  = 'cisession';
$config['sess_expiration']  = 7200;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = FALSE;
$config['sess_table_name']  = 'cisessions';
$config['sess_match_ip']  = FALSE;
$config['sess_match_useragent'] = FALSE;
$config['sess_time_to_update'] = 300;
 다음글 ci 용 테마와 플러그인 (2)
 이전글 namespace가 있는 라이브러리 (2)

댓글

변종원(웅파) / 2013/10/17 17:20:59 / 추천 0
cookie 관련된 것은 설정하신게 없는지요?
letsgolee / 2013/10/17 20:56:59 / 추천 0
 $config에서 cookie_domain 설정도 필요한 것으로 알고 있습니다. 그런데 이 값이 제대로 설정되었다 할지라도 되지 않을 가능성도 있습니다.

해보지 않아서 정확히 말하기는 어렵지만 안된다면 그것은 세션에 쿠키 도메인 값도 설정되어야 하는데 현재 codeigniter는 php에서 제공하는 session을 사용하는 것이 아니라 자체적으로 만든 것으로 하기 때문에 이 값을 설정할 수 없습니다. 

따라서 이 문제를 해결하려면 php의 자체 세션을 이용하는 방법을 쓰는 것인데요... 방법은 다음과 같습니다.

먼저 config에 정확한 쿠키 관련 설정도 합니다.

$config['cookie_prefix']    = "";
$config['cookie_domain']    = ".your-domain.com";
$config['cookie_path']      = "/";
cookie_domain은 예제에서 보듯이 도메인 앞에 점을 찍습니다. 그리고 다음 세션 파일을 application/libraries안에 MY_Session.php로 저장합니다.

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * Code Igniter
 *
 * An open source application development framework for PHP 4.3.2 or newer
 *
 * @package        CodeIgniter
 * @author        Dariusz Debowczyk
 * @copyright    Copyright (c) 2006, D.Debowczyk
 * @license        http://www.codeignitor.com/user_guide/license.html 
 * @link        http://www.codeigniter.com
 * @since        Version 1.0
 * @filesource
 */
 
// ------------------------------------------------------------------------

/**
 * Session class using native PHP session features and hardened against session fixation.
 * 
 * @package        CodeIgniter
 * @subpackage    Libraries
 * @category    Sessions
 * @author        Dariusz Debowczyk
 * @link        http://www.codeigniter.com/user_guide/libraries/sessions.html
 */
class MY_Session {
    var $session_id_ttl = 360; // session id time to live (TTL) in seconds
    var $flash_key = 'flash'; // prefix for "flash" variables (eg. flash:new:message)
    
    function MY_Session()
    {
        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);
/*
  $CI =& get_instance();
  
  session_set_cookie_params(0, $CI->config->item('cookie_path'));
  ini_set("session.cookie_domain", $CI->config->item('cookie_domain'));
*/
        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);
        session_unset();
        if ( isset( $_COOKIE[session_name()] ) )
        {
              setcookie(session_name(), '', time()-42000, '/');
        }
        session_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()
    {
  $CI =& get_instance();

  session_set_cookie_params(0, $CI->config->item('cookie_path'));
  ini_set("session.cookie_domain", $CI->config->item('cookie_domain'));

        session_start();
        
        // 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($key, $value)
    {
        $flash_key = $this->flash_key.':new:'.$key;
        $this->set_userdata($flash_key, $value);
    }
    
    /**
    * Keeps existing "flash" data available to next request.
    */
    function keep_flashdata($key)
    {
        $old_flash_key = $this->flash_key.':old:'.$key;
        $value = $this->userdata($old_flash_key);

        $new_flash_key = $this->flash_key.':new:'.$key;
        $this->set_userdata($new_flash_key, $value);
    }

    /**
    * Returns "flash" data for the given key.
    */
    function flashdata($key)
    {
        $flash_key = $this->flash_key.':old:'.$key;
        return $this->userdata($flash_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->flash_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->flash_key)
            {
                $this->unset_userdata($name);
            }
        }
    }
}
?>
그리고 테스트를 해보고 결과를 올려주시면... 다른 사람들에게도 도움이 될 것 같네요.

참고로 https://github.com/EllisLab/CodeIgniter 를 가면 차기 codeIgniter를 볼 수 있습니다. 버젼이 3.0-dev로 나오네요. 여기서는 세션이 드라이브 방식으로 변경이 될 예정 같아 보입니다. 그리고 제가 디비로 firebird를 공부하고 있는데 여기에 대한 지원도 있습니다.