3 回答
TA贡献1799条经验 获得超8个赞
这是一个老问题,但看起来没有得到适当的解决。在 CI 3.1.11 中,我重定向到支付网关,当网关完成支付并将控制权返回给会话时,会话变量“丢失”了。
事实上,他们只是没有重生。数小时(数天!!)后调查此事并尝试此处列出的所有选项和其他选项(均无效!),答案在于重新生成会话变量。
如果您的用户仅通过 LAN 访问系统,那么您可能无需执行前两个步骤:
在 system/libraries/Session/Session.php 中注释掉第 126 - 128 和 130 行。
//if (!isset($_SESSION['__ci_last_regenerate'])) {
// $_SESSION['__ci_last_regenerate'] = time();
//} elseif ($_SESSION['__ci_last_regenerate'] < (time() - $regenerate_time)) {
$this->sess_regenerate((bool) config_item('sess_regenerate_destroy'));
//}
原因是它在第 121 行$_SESSION['__ci_last_regenerate']之后没有恢复。session_start()因此$this->sess_regenerate()从未执行过。
第二步是确保注销函数正确清除缓存以防止注销后重新生成:
function logout() {
$this->session->sess_destroy();
$this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate, no-transform, max-age=0, post-check=0, pre-check=0");
$this->output->set_header("Pragma: no-cache");
redirect('logout');
}
如果您的用户将通过移动或 wifi 网络访问,那么您可能需要做更多的事情。在 PHP 文档中的 PHP 函数session_regenerate_id() 上,它给出了警告:
警告 目前,session_regenerate_id 不能很好地处理不稳定的网络,例如移动和 WiFi 网络。因此,您可能会通过调用 session_regenerate_id 遇到会话丢失的情况。
所以这就是我所做的:
找到session_id上次会话的。如果您的会话数据存储在数据库中,那么以下代码可能会很好地工作:
function latestSessionId() {
$CI = & get_instance();
$CI->db->reset_query();
$CI->db->select("id")->from($this->_config['save_path'])->order_by('timestamp','desc');
empty($this->config['match_ip']) OR $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']);
$result = $CI->db->get();
empty($result) OR $result = $result->row();
return empty($result) ? FALSE : $result->id;
}
按照此处的建议,然后在 session.php 的第 121 行执行以下操作:
$session_id = $this->latestSessionId();
session_id($session_id);
session_start();
将功能更改sess_regenerate为:
public function sess_regenerate($destroy = FALSE) {
$_SESSION['__ci_last_regenerate'] = time();
//session_regenerate_id($destroy);
if (session_status() !== PHP_SESSION_ACTIVE) {
$session_id = $this->latestSessionId();
session_id($session_id);
session_start();
}
}
更改config.php为参数sess_expiration和具有相同的值sess_time_to_update:
$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'cisession';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_time_to_update'] = 7200;
TA贡献1826条经验 获得超6个赞
这个错误可能是我在 codigniter 4 版本中遇到的
在你的 .env 文件中
cookie.prefix = ''
cookie.expires = 0
cookie.path = '/'
cookie.domain = ''
cookie.secure = true
cookie.httponly = false
cookie.samesite = 'None'
cookie.raw = false
此错误将解决
TA贡献1824条经验 获得超6个赞
下面的解决方案在 Codeigniter 中对我来说是正确的。如果您使用 重定向到支付网关header("Location: $url");
。只需exit();
在标题重定向后添加即可。因为您的会话被支付网关会话覆盖,他们会为其支付网关启动新会话。添加exit();
您的会话后,只要您的会话有效,您的域就会保持不变。最终代码将是
header("Location: $url");exit();
- 3 回答
- 0 关注
- 125 浏览
添加回答
举报