好的,我花了3天时间试图找出这里发生了什么,我很难过.

该网站使用CI构建. (http://horizoneslchina.com)

有一段时间,无论何时在中国,我都会得到不允许的关键人物.

我使用以下内容扩展了核心Input类:

<?PHP if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 
class MY_Input extends CI_Input {

    function _clean_input_keys($str)
    {
        $config=&get_config('config');
        if(!preg_match("/^[".$config['permitted_uri_chars']."]+$/i",rawurlencode($str)))
        {
            exit('disallowed Key Characters. '.$str);
        }

        //CleanUTF-8ifsupported
        if(UTF8_ENABLED===TRUE)
        {
            $str=$this->uni->clean_string($str);
        }

        return $str;

    }


}
/* End of file My_Input.PHP */

它似乎解决了这个问题,但现在我的情况是没有一个会话将保持不变.当中国某人登录并尝试访问任何安全页面时,会立即终止会话.

这在澳大利亚不会发生,在印度也不会发生.我能找到的唯一区别是在中文系统上,逗号放在会话名称前面. EG,_ci_session和上面的函数将此作为问题抛弃了.

有没有人对此有任何想法?

I also experienced alot of issues on CI sessions and ended up using this library for sessions ever since i am a happy man 

    <?PHP
/**
 The EckoTools Session Library

 @package The EckoTools Session Library
 @category Libraries
 @author Hartmut König (h.koenig@eckotools.com)
 @link http://www.okidoe.de
 @version 1.0.2
 @copyright Hartmut König 2009

 A class to handle sessions by using a MysqL database for session related
 data storage providing better security then the default session handler
 used by PHP with added protection against Session Hijacking & Fixation
 including the flashdata-Feature of CI. It don't use browser or IP to identify
 the user. Instead I generate a fingerprint of different seldom changing data
 (@link _generate_fingerprint)

 To prevent session hijacking,don't forget to use the {@link regenerate_id}
 method whenever you do a privilege change in your application

  --
  -- MysqL: Table structure for table `ci_sessions`
  --

CREATE TABLE `ci_sessions` (
  `session_id` varchar(32) NOT NULL default '',`fingerprint` varchar(32) NOT NULL default '',`session_data` blob NOT NULL,`session_expire` int(11) NOT NULL default '0',PRIMARY KEY  (`session_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


  This class is an adaptation between the original CI Sessions,Native Sessions
  and my own coding

*/

error_reporting(E_ALL);

class CI_Session
{

  /**
   *  Constructor of class
   *
   *  Initializes the class and starts a new session
   *
   *  There is no need to call start_session() after instantiating this class
   *
   *  $gc_maxlifetime    (optional) the number of seconds after which data will be seen as 'garbage' and
   *                     cleaned up on the next run of the gc (garbage collection) routine
   *
   *                     Default is specified in PHP.ini file
   *
   *  $gc_probability    (optional) used in conjunction with gc_divisor,is used to manage probability that
   *                     the gc routine is started. the probability is expressed by the formula
   *
   *                     probability = $gc_probability / $gc_divisor
   *
   *                     So if $gc_probability is 1 and $gc_divisor is 100 means that there is
   *                     a 1% chance the the gc routine will be called on each request
   *
   *                     Default is specified in PHP.ini file
   *
   *  $gc_divisor        (optional) used in conjunction with gc_probability,is used to manage probability
   *                     that the gc routine is started. the probability is expressed by the formula
   *
   *                     probability = $gc_probability / $gc_divisor
   *
   *                     So if $gc_probability is 1 and $gc_divisor is 100 means that there is
   *                     a 1% chance the the gc routine will be called on each request
   *
   *                     Default is specified in PHP.ini file
   *
   *  $security_code     (optional) the value of this argument is appended to the fingerprint before
   *                     creating the md5 hash out of it. this way we'll try to prevent fingerprint
   *                     spoofing
   *
   *                     Default is 'LeouOeEkKpvSnD-YCHd5ogt3y'
   *
   *  $table_name        (optional) You can change the name of that table by setting this property
   *
   *                  Default is 'ci_sessions'
   *
   *  @return void
   */
  function CI_Session(    $security_code="LeouOeEkKpvSnD-YCHd5ogt3y",$table_name="ci_sessions" )
  {
           //-- CI Config
           $this->CI                         = & get_instance();
        $this->flashdata_key     = 'flash'; // prefix for "flash" variables (eg. flash:new:message)
           $table_name                     = $this->CI->config->item('sess_table_name');
            $gc_maxlifetime                = $this->CI->config->item('sess_expiration');
            $gc_probability             = $this->CI->config->item('sess_gc_probability');
            $gc_divisor                        = $this->CI->config->item('sess_gc_divisor');
            $sess_name                        = $this->CI->config->item('sess_cookie_name');

      // if $gc_maxlifetime is specified and is an integer number
      (!empty($gc_maxlifetime) && is_integer($gc_maxlifetime))
                ? @ini_set('session.gc_maxlifetime',$gc_maxlifetime)
                : false;

      // if $gc_probability is specified and is an integer number
      (!empty($gc_probability) && is_integer($gc_probability))
                ? @ini_set('session.gc_probability',$gc_probability)
                : false;

      // if $gc_divisor is specified and is an integer number
      (!empty($gc_divisor) && is_integer($gc_divisor))
                ? @ini_set('session.gc_divisor',$gc_divisor)
                : false;

      (!empty($sess_name))
                ? @ini_set('session.name',$sess_name)
                : false;

      // get session lifetime
      $this->sessionLifetime = ini_get("session.gc_maxlifetime");

      // we'll use this later in order to prevent fingerprint spoofing
      $this->securityCode = $security_code;
      $this->tableName         = $table_name;

      // register the new handler
      session_set_save_handler(
          array(&$this,'_open'),array(&$this,'_close'),'_read'),'_write'),'_destroy'),'_gc')
            );
      register_shutdown_function('session_write_close');

      // start the session
      session_start();

            // 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();
  }
    /**
    * Reads given session attribute value
    *
    * @return integer sessionvalue
    */
    function userdata($item)
    {
            //added for backward-compatibility
        if($item == 'session_id')
            {
          return session_id();
            }

            if(isset($_SESSION[$item]))
                {
                return($_SESSION[$item]);
            }

            return(false);
    }
    /**
     * Fetch all session data
     *
     * @access    public
     * @return    mixed
     */
    function all_userdata()
    {
        return ( ! isset($_SESSION)) ? FALSE : $_SESSION;
    }

    /**
    * Sets session attributes to the given values
    *
    * @return void
    */
    function set_userdata($newdata = array(),$newval = '')
    {
        (is_string($newdata))
            ? $newdata = array($newdata => $newval)
            : false;

        if(count($newdata) > 0)
            {
          foreach($newdata as $key => $val)
            {
            $_SESSION[$key] = $val;
            }
            }
    }
    /**
    * Erases given session attributes
    *
    * @return void
    */
    function unset_userdata($newdata = array())
    {
        (is_string($newdata))
            ? $newdata = array($newdata => '')
            : false;

        if(count($newdata) > 0)
            {
          foreach ($newdata as $key => $val)
            {
            unset($_SESSION[$key]);
            }
            }
    }
  /**
   *  Deletes all data related to the session
   *  @return void
   */
  function sess_destroy()
  {
      $this->regenerate_id();
      session_unset();
      session_destroy();
  }

  /**
   *  Regenerates the session id.
   *
   *  <b>Call this method whenever you do a privilege change!</b>
   *
   *  @return void
   */
  function regenerate_id()
  {
      // saves the old session's id
      $oldSessionID = session_id();

      // regenerates the id
      // this function will create a new session,with a new id and containing the data from the old session
      // but will not delete the old session
      session_regenerate_id();

      // because the session_regenerate_id() function does not delete the old session,// we have to delete it manually
      $this->_destroy($oldSessionID);
  }
    /**
     * Add or change flashdata,only available
     * until the next request
     *
     * @access    public
     * @param    mixed
     * @param    string
     * @return    void
     */
    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 flashdata available to next request.
     *
     * @access    public
     * @param    string
     * @return    void
     */
    function keep_flashdata($key)
    {
        // 'old' flashdata gets removed.  Here we mark all
        // flashdata as 'new' to preserve it from _flashdata_sweep()
        // Note the function will return FALSE if the $key
        // provided cannot be found
        $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);
    }

    // ------------------------------------------------------------------------

    /**
     * Fetch a specific flashdata item from the session array
     *
     * @access    public
     * @param    string
     * @return    string
     */
    function flashdata($key)
    {
        $flashdata_key = $this->flashdata_key.':old:'.$key;
        return $this->userdata($flashdata_key);
    }

    // ------------------------------------------------------------------------

    /**
     * Identifies flashdata as 'old' for removal
     * when _flashdata_sweep() runs.
     *
     * @access    private
     * @return    void
     */
    function _flashdata_mark()
    {
        $userdata = $this->all_userdata();
        foreach ($userdata 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);
            }
        }
    }

    // ------------------------------------------------------------------------

    /**
     * Removes all flashdata marked as 'old'
     *
     * @access    private
     * @return    void
     */

    function _flashdata_sweep()
    {
        $userdata = $this->all_userdata();
        foreach($userdata as $key => $value)
            {
            if (strpos($key,':old:'))
                {
                $this->unset_userdata($key);
                }
            }
    }
  /**
   *  Get the number of online users
   *
   *  @return integer     number of users currently online
   */
  function get_users_online()
  {
      // counts the rows from the database
      $query     = $this->CI->db->query("SELECT COUNT(session_id) as count FROM ".$this->tableName);
      $result = $query->row();

      // return the number of found rows
      return $result->count;
  }

    /**
     * Generates key as protection against Session Hijacking & Fixation.
     * @access private
     * @return string
     */
    function _generate_fingerprint()
    {
        //-- We don't use the ip-adress,because this is a subject to change in most cases (proxies etc.)
        $list = array('HTTP_ACCEPT_CHARSET','HTTP_ACCEPT_ENCODING','HTTP_ACCEPT_LANGUAGE','HTTP_USER_AGENT');
        $key = array($this->securityCode);
        foreach($list as $item)
            {
            $key[] = $this->CI->input->server($item);
            }
        return md5(implode("\0",$key));
    }
  /**
   *  Custom open() function
   *
   *  @access private
   */
  function _open($save_path,$session_name)
  {
      return(true);
  }

  /**
   *  Custom close() function
   *
   *  @access private
   */
  function _close()
  {
      return(true);
  }

  /**
   *  Custom read() function
   *
   *  @access private
   */
  function _read($session_id)
  {
      // reads session data associated with the session id
      // but only
      // - if the fingerprint is the same as the one who had prevIoUsly written to this session AND
      // - if session has not expired
      $result = $this->CI->db->query("SELECT session_data ".
                                                                      "FROM ".$this->tableName." ".
                                                                      "WHERE session_id = ".$this->CI->db->escape($session_id)." ".
                                                                      "AND fingerprint = ".$this->CI->db->escape($this->_generate_fingerprint())." ".
                                                                      "AND session_expire > '".time()."' LIMIT 1");

      // if anything was found
      if($result->num_rows() > 0)
          {
        // return found data
        $fields = $result->row();

        // Unserialization - PHP handles this automatically
        return $fields->session_data;
          }

      // if there was an error return an empty string - this HAS to be an empty string
      return("");

  }

  /**
   *  Custom write() function
   *
   *  @access private
   */
  function _write($session_id,$session_data)
  {
      // insert OR update session's data - this is how it works:
      // first it tries to insert a new row in the database BUT if session_id is already in the database then just
      // update session_data and session_expire for that specific session_id
      // read more here http://dev.MysqL.com/doc/refman/4.1/en/insert-on-duplicate.html
      $result = $this->CI->db->query(
                                                              "INSERT INTO ".$this->tableName." (".
                                                        "session_id,".
                                                        "fingerprint,".
                                                        "session_data,".
                                                        "session_expire".
                                                    ") VALUES (".
                                                              $this->CI->db->escape($session_id).",".
                                                              $this->CI->db->escape($this->_generate_fingerprint()).",".
                                                              $this->CI->db->escape($session_data).",".
                                                              $this->CI->db->escape(time() + $this->sessionLifetime).
                                                                  ")".
                                                          "ON DUPLICATE KEY UPDATE ".
                                                                  "session_data = ".$this->CI->db->escape($session_data).",".
                                                              "session_expire = ".$this->CI->db->escape(time() + $this->sessionLifetime));

            // note that after this type of queries,MysqL_affected_rows() returns
            // - 1 if the row was inserted
            // - 2 if the row was updated
            switch($this->CI->db->affected_rows())
                {
          // if the row was inserted
          case 1:
                    return("");
        break;
                // if the row was updated
                case 2:
              return(true);
                break;
                // if something went wrong,return false
                default:
              return(false);
          break;
          }
  }

  /**
   *  Custom destroy() function
   *
   *  @access private
   */
  function _destroy($session_id)
  {
      // deletes the current session id from the database
      $result = $this->CI->db->query("DELETE FROM ".$this->tableName." ".
                                                                  "WHERE session_id = ".$this->CI->db->escape($session_id));

      // if anything happened
      if($this->CI->db->affected_rows())
          {
        return(true);
                }

      // if something went wrong,return false
      return(false);
  }

  /**
   *  Custom gc() function (garbage collector)
   *
   *  @access private
   */
function _gc($maxlifetime)
  {
        // it deletes expired sessions from database
    $result = $this->CI->db->query("DELETE FROM ".$this->tableName." ".
                                                                    "WHERE session_expire < ".$this->CI->db->escape(time() - $maxlifetime));
    }

}
?>

php – CodeIgniter会话仅在中国失败的更多相关文章

  1. HTML5 Web缓存和运用程序缓存(cookie,session)

    这篇文章主要介绍了HTML5 Web缓存和运用程序缓存(cookie,session),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. iOS Swift上弃用后Twitter.sharedInstance().session()?. userName的替代方案

    解决方法如果您仍在寻找解决方案,请参阅以下内容:

  3. 使用Fabric SDK iOS访问Twitter用户时间线

    我试图在这个问题上挣扎两天.我正在使用FabricSDK和Rest工具包,试图为Twitter使用不同的RestAPIWeb服务.我可以使用具有authTokenSecret,authToken和其他值的会话对象的TWTRLogInButton成功登录.当我尝试获取用户时间线时,我总是得到失败的响应,作为:{“errors”:[{“code”:215,“message”:“BadAuthentic

  4. ios – 如何从Apple Watch调用iPhone上定义的方法

    有没有办法从Watchkit扩展中调用iPhone上的类中定义的方法?根据我的理解,目前在Watchkit和iPhone之间进行本地通信的方法之一是使用NSUserDefaults,但还有其他方法吗?

  5. ios – 如何将视频从AVAssetExportSession保存到相机胶卷?

    在此先感谢您的帮助.解决方法只需使用session.outputURL=…

  6. ios – 使用AVCaptureSession sessionPreset = AVCaptureSessionPresetPhoto拉伸捕获的照片

    解决方法所以我解决了我的问题.这是我现在使用的代码,它工作正常:…重要的输出imagaView:一些额外的信息:相机图层必须是全屏,并且outputimageView也必须是.我希望这些对某些人来说也是有用的信息.

  7. 我可以在iOS中自定义Twitter工具包的登录按钮吗?

    我已经下载了Twitter工具包框架并添加了用Twitter登录的代码.但是,我不希望登录按钮看起来像那样.我想要一个用于登录的自定义按钮.我能这样做吗?我只想使用这个框架,因为这也适用于iOS系统帐户.解决方法根据document:在按下按钮中添加代码:Objective-C的迅速

  8. ios – AVCaptureSession条形码扫描

    解决方法以下是我所拥有的项目代码示例,可以帮助您走上正确的轨道

  9. ios – 如何在Watch OS 2中引用不支持的框架

    有没有办法将框架链接到扩展名?

  10. ios7 – 在iOS 7中设置Alamofire中的自定义HTTP标头不工作

    解决方法我得到它的工作这对iOS7没有影响:然而,这将适用于iOS7和8:

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部