【问题标题】:CodeIgniter Session breaks on non-sticky-session load balanced serverCodeIgniter 会话在非粘性会话负载平衡服务器上中断
【发布时间】:2014-04-23 12:11:54
【问题描述】:

我有一个棘手的问题;我已经用了一个月左右,所以我进行了广泛的研究。

我有一个托管的 CodeIgniter 网站 - 不是我的选择,也不是我有权更改的任何东西 - 由第三方在 2 台服务器上,由第三方进行负载平衡。有趣的是负载均衡器随机选择服务器,没有粘性会话。

现在,默认情况下 CI 应该使用 cookie 或将会话存储在数据库中来处理这个问题。我们已将会话设置为自动加载,

$autoload['libraries'] = array('session', 'user_agent', 'rest_client', 'lib_log');

配置为会话和 cookie 设置了这个:

/*
|--------------------------------------------------------------------------
| Session Variables
|--------------------------------------------------------------------------
|
| 'sess_cookie_name'        = the name you want for the cookie
| 'sess_expiration'         = the number of SECONDS you want the session to     last.
|   by default sessions last 7200 seconds (two hours).  Set to zero for no expiration.
| 'sess_expire_on_close'    = Whether to cause the session to expire automatically
|   when the browser window is closed
| 'sess_encrypt_cookie'     = Whether to encrypt the cookie
| 'sess_use_database'       = Whether to save the session data to a database
| 'sess_table_name'         = The name of the session database table
| 'sess_match_ip'           = Whether to match the user's IP address when reading the session data
| 'sess_match_useragent'    = Whether to match the User Agent when reading the session data
| 'sess_time_to_update'     = how many seconds between CI refreshing Session Information
|
*/
$config['sess_cookie_name']     = 'e1fdc095-98e2-4294-9584-362ba355bacf';

$config['sess_expiration']      = 3600;
$config['sess_expire_on_close']= TRUE;
$config['sess_encrypt_cookie']  = TRUE;
$config['sess_use_database']    = FALSE; // obviously used TRUE when trying to use DB
$config['sess_table_name']      = 'ci_sessions';
$config['sess_match_ip']        = FALSE;
$config['sess_match_useragent']= TRUE;
$config['sess_time_to_update']  = 300;

/*
|--------------------------------------------------------------------------
| Cookie Related Variables
|--------------------------------------------------------------------------
|
| 'cookie_prefix' = Set a prefix if you need to avoid collisions
| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
| 'cookie_path'   =  Typically will be a forward slash
| 'cookie_secure' =  Cookies will only be set if a secure HTTPS connection exists.
|
*/
$config['cookie_prefix']    = "";
$config['cookie_domain']    = "";
$config['cookie_path']  = "/";
$config['cookie_secure']    = TRUE;
$config['cookie_httponly']  = TRUE;

(我希望该配置中的某些内容有问题?sess_cookie_name 太长了?sess_match_ip 应该是真的?)

1) 使用 cookie:站点在单个节点上工作,但当请求被定向到另一台服务器时会话消失。当请求被定向到原始服务器时,会话又回来了。这通常(但并非总是如此——有时用户很幸运,所有请求都转到一台服务器)导致无限的重定向循环(直到浏览器停止尝试)。

有趣的是,在这种情况下,登录时的标准行为是从创建会话的控制器/方法 (A/login) 移动到另一个控制器中的方法 (B/index),再到同一控制器中的方法 (@ 987654327@)。始终是B/welcome 无法识别会话,并重定向回A/login。然后循环开始,A/login 识别会话。

2) 使用数据库:未创建会话,并且显然(我无法监视数据库)该会话也未在数据库中创建。这还没有被充分探索,部分原因是数据库中会话的唯一 ID 必须存储在客户端上,而唯一的地方就是 cookie。如果完全使用 cookie,为什么要使用数据库?

(第三方主持人也回滚了该尝试,很难让他们进一步做任何事情)

因此,如果负载完全仅在一台服务器上,但当负载平衡器按预期运行时失败,我有一个站点可以在我的(单个)服务器上运行 100%,在他们的服务器上运行。 cookie 和 DB 存储方法都是如此。

我束手无策。如果有人有任何可能的解决方案或建议,请告诉我。

【问题讨论】:

    标签: codeigniter session load-balancing


    【解决方案1】:

    我终于可以访问类似的设置,并复制了问题。但是,我也解决了这个问题..我只是不知道如何。正是通过破解并最终替换了 CI 的整个 /system 文件夹,我才让它工作。

    FWIW,上面的配置设置

    $config['cookie_secure']    = TRUE;
    $config['cookie_httponly']  = TRUE;
    

    没用; cookie_secure 必须为 false,即使该站点有证书。我在其他地方读到证书在负载平衡环境中的安装方式会影响这一点。 cookie_httponly 是非标准的,显然没有效果。

    抱歉,我没有更好的建议。

    【讨论】:

      猜你喜欢
      • 2018-09-09
      • 2018-03-20
      • 2021-09-06
      • 2013-04-18
      • 2011-09-23
      • 2019-01-21
      • 2012-03-12
      • 2020-10-29
      • 2018-04-05
      相关资源
      最近更新 更多