SagePay/Chrome80/3D-Secure/Samesite和丢失的会话ID



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

随着Chrome 80中对samesite cookie的更改,交易一直无法正确回调-找不到交易。付款完成,但会话/交易参考似乎丢失,因此订单状态不会更新。我认为这是因为处理cookie的方式发生了变化,重定向到3D安全屏幕打破了这一点。

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

有没有其他人遇到这个问题并知道解决方法?

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

解决方案:

首先,确保您使用的php版本是7.3或更高版本。对于这个解决方案,至少需要7.3版本,但如果你使用的是较低版本,你可以通过查看我提供的源代码来更改代码,我没有添加它,因为我无法测试它。再次,我应该提到的是,我在Opencart 2.3版本上尝试过这个解决方案。它运行起来没有任何问题。我将在下面给出详细信息,但通常我已经通过添加"samesite"=>解决了这个问题"None"和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.目录/控制器/启动/启动.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((命令。事实上,前两个文件的更改已经足够了,但我仍然建议扫描其他文件,以避免任何意外。

最新更新