php - SagePay/Chrome 80/3D Secure/Samesite 和丢失的 session ID

标签 php google-chrome opencart

我继承了一个使用 SagePay Direct 进行支付的 Opencart 2.0.1.1 网站。

随着 Chrome 80 交易中相同站点 cookie 的更改,无法正确回调 - 未找到交易。付款通过,但似乎 session /交易引用丢失,因此订单状态不会更新。我认为这是因为 cookie 的处理方式发生了变化,并且重定向到 3D 安全屏幕打破了这一点。

我已将 session cookie 更新为 samesite=None 并将其设置为安全,但这并没有解决问题。目前支付可以在其他浏览器中使用,并且当使用网站的本地开发副本和 SagePay 的测试服务 Chrome 运行时也可以使用。

有没有其他人遇到过这个问题并知道修复方法?

我不认为更新 OpenCart 是一个可行的选择,因为一些核心文件已经被以前的开发人员调整过,但我不知道是哪个。

最佳答案

解决方案:
首先,请确保您使用的 php 版本是 7.3 或更高版本。对于这个方案,至少需要7.3版本,但是如果你使用的是低版本,你可以通过查看我提供的源代码来更改代码,我没有添加它,因为我无法测试它。再次,我应该提到我在 Opencart 2.3 版本上尝试过这个解决方案,它没有任何问题。我将在下面提供详细信息,但通常我已经通过在 session_start() 和 setcookie() 命令之前添加“相同站点”=>“无”和安全参数来解决它。
1. system/library/session.php
找:

session_set_cookie_params(0, '/');
session_start();
代替:
if (PHP_VERSION_ID < 70300) {
    session_set_cookie_params(0, '/; samesite=None', '.yoursite.com', true, true);
} else {
    ini_set('session.cookie_samesite', 'None');
    session_set_cookie_params([
        'lifetime' => 0,
        'path' => '/',
        'domain' => '.yoursite.com',
        'secure' => true,
        'httponly' => true,
        'samesite' => 'None'
    ]);
}
session_start();
找:
if ($key != 'PHPSESSID') {
    setcookie($key, $this->session_id, ini_get('session.cookie_lifetime'), ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly'));
}
代替:
if (PHP_VERSION_ID < 70300) {
    setcookie($key, $this->session_id, ini_get('session.cookie_lifetime'), ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly'));
} else {
    $samsite_cookie_options = array (
        'expires' => ini_get('session.cookie_lifetime'),
        'path' => ini_get('session.cookie_path'),
        'domain' => ini_get('session.cookie_domain'),
        'secure' => true, // or false
        'httponly' => true, // or false
        'samesite' => 'None' // None || Lax || Strict
    );
    setcookie($key, $this->session_id, $samsite_cookie_options);
}
找:
setcookie($key, '', time() - 42000, ini_get('session.cookie_path'), ini_get('session.cookie_domain'));
代替:
if (PHP_VERSION_ID < 70300) {
    setcookie($key, '', time() - 42000, ini_get('session.cookie_path'), ini_get('session.cookie_domain'));
} else {
    $samsite_cookie_options = array (
        'expires' => time() - 42000,
        'path' => ini_get('session.cookie_path'),
        'domain' => ini_get('session.cookie_domain'),
        'secure' => true, // or false
        'httponly' => true, // or false
        'samesite' => 'None' // None || Lax || Strict
    );
    setcookie($key, '', $samsite_cookie_options);
}
2.目录/ Controller /startup/startup.php
找:
setcookie('language', $code, time() + 60 * 60 * 24 * 30, '/', $this->request->server['HTTP_HOST']);
代替:
if (PHP_VERSION_ID < 70300) {
    setcookie('language', $code, time() + 60 * 60 * 24 * 30, '/', $this->request->server['HTTP_HOST']);
} else {
    $samsite_cookie_options = array (
        'expires' => time() + 60 * 60 * 24 * 30,
        'path' => '/',
        'domain' => $this->request->server['HTTP_HOST'],
        'secure' => true, // or false
        'httponly' => true, // or false
        'samesite' => 'None' // None || Lax || Strict
    );
    setcookie('language', $code, $samsite_cookie_options);
}
找:
setcookie('tracking', $this->request->get['tracking'], time() + 3600 * 24 * 1000, '/');
代替:
if (PHP_VERSION_ID < 70300) {
    setcookie('tracking', $this->request->get['tracking'], time() + 3600 * 24 * 1000, '/');
} else {
    $samsite_cookie_options = array (
        'expires' => time() + 3600 * 24 * 1000,
        'path' => '/',
        'domain' => $this->request->server['HTTP_HOST'],
        'secure' => true, // or false
        'httponly' => true, // or false
        'samesite' => 'None' // None || Lax || Strict
    );
    setcookie('tracking', $this->request->get['tracking'], $samsite_cookie_options);
}
找:
setcookie('currency', $code, time() + 60 * 60 * 24 * 30, '/', $this->request->server['HTTP_HOST']);
代替:
if (PHP_VERSION_ID < 70300) {
    setcookie('currency', $code, time() + 60 * 60 * 24 * 30, '/', $this->request->server['HTTP_HOST']);
} else {
    $samsite_cookie_options = array (
        'expires' => time() + 60 * 60 * 24 * 30,
        'path' => '/',
        'domain' => $this->request->server['HTTP_HOST'],
        'secure' => true, // or false
        'httponly' => true, // or false
        'samesite' => 'None' // None || Lax || Strict
    );
    setcookie('currency', $code, $samsite_cookie_options);
}
3. 搜索所有文件并更改 session_start() 和 setcookie() 命令,如上所述。实际上,前两个文件的更改已经足够了,但我仍然建议扫描您的其他文件以避免任何意外。

关于php - SagePay/Chrome 80/3D Secure/Samesite 和丢失的 session ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61462635/

相关文章:

python - DJango 设置中的 SECURE_PROXY_SSL_HEADER 导致 CORS 预检 301 响应状态代码(和失败)

google-chrome - 如何从 chrome 扩展访问 IndexedDB(当前打开的域/选项卡)

php - 如何在opencart中使用多个数据库?

categories - 如何在opencart中显示从子类别到父类别的产品?

css - 将 Bootstrap 移动布局从一列更改为两列

php - 将 IF 语句与 INSERT IGNORE 结合使用

php包含文件执行失败

php - Gii:类不存在或有语法错误

php - 根据域名更改网页标题的脚本

CSS 用于修复 Chrome 中 Wordpress 中的垂直 Logo 对齐问题