You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter从CyberSource支付网关重定向后会话丢失求解决方案

解决CodeIgniter 3.x + CyberSource回调时会话丢失问题

核心原因

CyberSource回调属于跨站请求,Chrome等现代浏览器默认对SameSite=Lax的Cookie有跨站传递限制,而CodeIgniter 3.x原生不支持配置SameSite属性,直接在cookie_path里拼接;SameSite=None会因CI内部Cookie处理逻辑问题不生效,导致回调时会话Cookie无法被携带,进而丢失登录状态。

正确解决方案

1. 修复Session Cookie的SameSite配置(推荐,不破坏系统文件的方式)

由于CI3原生不支持SameSite,需要手动修改Session驱动的Cookie设置逻辑,推荐自定义Session驱动:

方法:自定义Session Cookie驱动

  1. 在application/libraries/Session/drivers目录下创建MY_Session_cookie_driver.php(如果使用数据库会话驱动,则对应创建MY_Session_database_driver.php),内容如下:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class MY_Session_cookie_driver extends CI_Session_cookie_driver {

    protected function _set_cookie($session_id)
    {
        if (is_null($session_id))
        {
            return $this->_destroy();
        }

        $expire = ($this->_config['sess_expiration'] === 0) ? 0 : time() + $this->_config['sess_expiration'];

        // 用PHP7.3+支持的数组方式设置Cookie参数,添加SameSite=None
        $cookie_options = [
            'expires'  => $expire,
            'path'     => $this->_config['cookie_path'],
            'domain'   => $this->_config['cookie_domain'],
            'secure'   => $this->_config['cookie_secure'],
            'httponly' => $this->_config['cookie_httponly'],
            'samesite' => 'None'
        ];

        return setcookie($this->_config['cookie_name'], $session_id, $cookie_options);
    }
}
  1. 确保config.php里的Cookie配置正确:
$config['cookie_secure'] = TRUE; // HTTPS环境必须设为TRUE,SameSite=None要求搭配Secure属性
$config['cookie_domain'] = '.yourdomain.com'; // 根域名格式,确保跨子域名可用(按需设置)
$config['cookie_path'] = '/';
$config['cookie_httponly'] = TRUE;
$config['sess_expiration'] = 7200; // 会话过期时间设为2小时,覆盖支付流程时长

2. 恢复错误的Session配置

之前修改system/libraries/Session/session.php中session.name为session.id的操作逻辑错误,会导致会话ID混乱,必须改回原代码:

ini_set('session.name', $params['cookie_name']);

3. 排除其他干扰项

  • CSRF验证拦截:如果开启了CI的CSRF验证,必须将CyberSource的回调URI加入白名单:
    $config['csrf_exclude_uris'] = ['payments/cybersource_callback']; // 替换为你的实际回调URI
    
  • 会话存储权限:如果使用文件会话,确保application/sessions目录权限为700,且归属Web服务器用户;如果使用数据库会话,检查会话表是否正常存储数据,未被提前清理。

验证步骤

  1. 登录应用后,打开浏览器开发者工具(F12)→ Application → Cookies,查看会话Cookie的SameSite属性是否为None,Secure是否为true。
  2. 发起支付并触发回调,在回调控制器的方法开头添加调试代码:
    var_dump($this->session->userdata('user_id')); // 打印用户ID,确认是否存在
    var_dump(session_id()); // 打印会话ID,对比登录时的ID是否一致
    

内容的提问来源于stack exchange,提问作者Nishant Solanki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 20:55:25