【问题标题】:Cannot retrieve session id using session class in CodeIgniter无法使用 CodeIgniter 中的会话类检索会话 ID
【发布时间】:2014-03-04 16:52:32
【问题描述】:

我的控制器中有这段代码

class Upload_center extends Controller 
{
    function __construct()
    {
        parent::Controller();
        $this->load->model('auth_model') ;
        if(!$this->auth_model->authorize())
        {
            redirect('login');

        } 

    }

我认为有这段代码

$('#swfupload-control').swfupload({
    upload_url: "<?=base_url()?>index.php/upload_center/upload",
    file_post_name: 'fileupload',
    file_size_limit : "200000000",
    file_types : "*.zip;*.rar;*.pdf;*.doc;*.docx;*.mp3;*.avi;*.wmv;*.docx;*.jpg;*.jpeg;*.JPG;*.JPEG;*.png;*.gif;*.bitmap;",
    file_types_description : "zip files ",
    post_params: {"PHPSESSID": "<?=$this->session->userdata('session_id');?>"} ,
    file_upload_limit : 1,
    flash_url : "<?=base_url()?>js/jquery-swfupload/js/swfupload/swfupload.swf",
    button_image_url : '<?=base_url()?>js/jquery-swfupload/js/swfupload/wdp_buttons_upload_114x29.png',
    button_width : 114,
    button_height : 29,
    button_placeholder : $('#button')[0],
    debug: false

我希望用户在登录后上传他们的文件,所以我有一种方法需要用户在继续上传文件之前先登录。虽然在我看来我使用的是 flash 上传器,但我认为它没有传递会话值,PHP 认为用户没有登录并将他重定向到登录页面。我通过邮件发送phpsessionid,但仍然没有发送。

【问题讨论】:

    标签: session codeigniter


    【解决方案1】:

    您的会话 cookie 到期时间设置为多少? CodeIgniter 中有一个已知错误,如果您停留在使 AJAX 重新请求超过 cookie 过期的页面上,它将重置数据库中的会话 id,但无法在浏览器 cookie 中设置它,因为它是异步的要求。这会导致下一个非异步 GET 请求断开连接,从而导致会话库调用 sess_destroy()。如果这听起来像你的情况,请告诉我。否则,请提供更详细的信息。

    编辑:我或许还应该在此处包含此错误的修复。在 /application/libraries 中创建一个名为“MY_Session.php”的文件(如果它尚不存在)。在那里你可以粘贴这个:

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    /*
    * 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 ( !isAjax() ){
                parent::sess_update();
            }
        }
    }
    ?>
    

    isAjax() 函数是我在 /application/helpers/isajax_helper.php 中的一个助手,如下所示:

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    /**
    * is_ajax_call
    *
    * Determines if the current page request is done through an AJAX call
    *
    * @access    public
    * @param    void
    * @return    boolean
    */
    if ( ! function_exists('isAjax')) {
        function isAjax() {
            return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
        }
    }
    ?>
    

    在我的配置文件中引用如下:

    $autoload['helper'] = array('otherhelper1', 'isajax', 'otherhelper2');
    

    【讨论】:

    • 您现在可以 [从 2.0.x 开始] 使用 $this-&gt;input-&gt;is_ajax_request() 而不是创建 isAjax()
    【解决方案2】:

    默认情况下,CI 在定义的时间间隔内创建一个新的 sessionid。查看配置以查看默认值(我相信是 5 分钟)。所以$this-&gt;session-&gt;userdata('session_id') 将始终包含不同的 ID,但 CI 仍然能够知道您是谁。

    出于完全相同的原因,我遇到了这个问题。我知道为什么 CI 人员创建了这次会议茶点,但我觉得它让事情变得更加复杂。您可以通过简单地为会话刷新输入更高的值来覆盖配置中的此行为。

    在我的一个应用中,它看起来像这样:

    $config['sess_expiration']  = 7200;
    //$config['sess_time_to_update'] = 300;
    $config['sess_time_to_update'] = $config['sess_expiration'];
    

    这样,我可以像没有框架一样使用会话。

    【讨论】:

      【解决方案3】:

      不可能。 Session 类不使用原生 PHP 会话。

      我推荐你的最佳实践

      contoller contain uploadpage {
          function index(){
              $dataview['session_id'] = $this->secureUpload();
              $this->load->view('upload',$dataview);
          }
          function secureUpload(){
              $user_id =  $this->session->userdata('cuser_id');
              $md5pass = $this->basemodel->_getEncrypPassFromDb($user_id);
              $time =time();
              $session = md5($user_id.$time.$md5pass)."x".$user_id."x".$time;
              return $session;
          }
      }
      

      上传页面

      ('#swfupload-control').swfupload({
          post_params: {"PHPSESSID": "<?=session_id?>"} ,
      

      这样可以解密你的安全代码

             function upload_function(){
      
                  list($session2, $user_id, $time) = explode("x", $session);
          $this->load->library('upload', $config);
          $md5pass = $this->basemodel->_getMD5pass($user_id);
          $session_server = md5($user_id.$time.$md5pass)."x".$user_id."x".$time;
      
          if($session_server == $session){
                   upload file by flash upload
                  }
      

      }

      【讨论】:

        【解决方案4】:

        我只是遇到了这个问题,ajax 调用破坏了我登录的用户会话。这是根据 Sturgeon 先生的建议使用 CI 2.1.2 的@treeface 解决方案。我猜输入和加载库没有在 CI_Session 中自动加载,所以我必须获取 CI 对象的实例才能完成这项工作。

        <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
        /*
        * Session Class Extension
        */
        class MY_Session extends CI_Session {
        
            protected $_CI;
        
        /*
        * Do not update an existing session on ajax calls
        *
        * @access    public
        * @return    void
        */
        function sess_update() {
        
            $this->_CI =& get_instance();
        
                if ( !$this->_CI->input->is_ajax_request() ){
                    parent::sess_update();
               }
           }
        }
        

        【讨论】:

          【解决方案5】:

          我想你应该看看这个 http://ellislab.com/forums/viewthread/138823/
          它解释了摆脱问题

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-02
            • 2017-05-16
            相关资源
            最近更新 更多