Chrome 80 Magento cookie sorunu çözümü

Hidayet Ok
4 min readMar 21, 2020

--

Destek verdiğim bazı sitelerin 2 hafta kadar önce başlayan sipariş sonrası ödeme tamamlayamama sorunu üzerine konuyu biraz inceledik.

Sitelerde sipariş tamamlama esnasında 3D secure sayfasına gidilip başarılı veya başarısız dönüş sonrası oturum ve sepet bilgisi kayboluyordu. Hem yaptığım araştırmalarda hem de attığım bir tweet’e gelen cevaplarda şüphelinin Chrome’un yeni çıkan 80 versiyonu olduğu ortaya çıktı.

Chrome 80 versiyonuyla birlikte bir cookie parametresi olan SameSite değeri eğer None ise cookie’nin Secure işaretli olmasını şart koşuyordu. Magento müşteri sayfaları ve checkout dışındaki alanlarda sayfa https bile Secure paremetresini işaretlemiyor. Kod içinde yapılan bir değişiklikle tümünü Secure işaretledik ama sorun devam etti.

PHP ise SameSite parametresini 7.3 den sonra eklediği için 7.3 öncesi versiyonlarda setcookie komutu bu parametreyi işaretleyemiyor.

Edit 10 Şubat 2021 : Magento 2.4.2 çıktı ve resmi olarak SameSite desteği eklendi. https://devdocs-beta.magento.com/guides/v2.4/release-notes/open-source-2-4-2.html

Magento 1:

Biraz araştırma ile bulduğum bir kod parçasını Magento içine uyarladım ve aşağıdaki çözüm ortaya çıktı.

Not : Başlamadan önce magento1'deki compilation ( derleme ) özelliğinin kapalı olduğundan emin olunuz.

1 ) Öncelikle app/code/core/Mage/Core/Model/Cookie.php dosyasını app/code/local/Mage/Core/Model/Cookie.php olarak kopyalayın.

2 ) app/code/local/Mage/Core/Model/Cookie.php dosyasında 309. satır civarında setcookie komutunu bulun ve önüne // veya # koyarak bu satırı yoruma çevirin. Bu satırın hemen altına aşağıdaki kodu ekleyin.

if (PHP_VERSION_ID < 70300) {
setcookie($name, null, null, $path.'; samesite=None', $domain, $secure, $httponly);
}
else {
setcookie($name, null, [
'expires' => $expire,
'path' => $path,
'domain' => $domain,
'samesite' => 'None',
'secure' => $secure,
'httponly' => $httponly,
]);
}

3 ) Aynı dosyada 239. satır civarında yine setcookie komutunu bulup önüne // ekleyerek yoruma çevirin ve hemen alt satırına aşağıdaki kodu ekleyin.

if (PHP_VERSION_ID < 70300) {
setcookie($name, $value, $expire, $path."; samesite=None", $domain, $secure, $httponly);
}
else {
setcookie($name, $value, [
'expires' => $expire,
'path' => $path,
'domain' => $domain,
'samesite' => 'None',
'secure' => $secure,
'httponly' => $httponly,
]);
}

4 ) Aynı dosyada 184. satır civarında isSecure() fonksiyonu var. O fonksiyonun ilk satırı aşağıdaki gibi “return true;” olacak şekilde değiştir.

public function isSecure()
{
return true;
if ($this->getStore()->isAdmin()) {
return $this->_getRequest()->isSecure();
}
return false;
}

5 ) Bu değişiklikler sonrası eğer gerekiyorsa web sunucunuzu ya da php-fpm sunucusunu yeniden başlatın.

Bu işlemlerden sonra Chrome ile siteye girip;

6 ) f12 ye basıp Applications / Cookies kısmında siteyi bulun.

7 ) “frontend” isimli cookienin Secure parametresi ana sayfadayken işaretli mi kontrol edin,

8 ) Aynı cookienin SameSite parametresi None olmalıdır.

Bu kontrollerden sonra sipariş testinizi yapın. Ödeme aşamasından sonra 3D secure sayfasına gidip dönüldüğünde başarılı ödeme ise başarılı ekranına, başarısız ödemede ise sepete düşebilmesi ve sepetteki ürünlerin yerinde duruyor olması gerekir.

Örnek kodu şuradan buldum : https://stackoverflow.com/a/59654832/1182352

Magento 2 :

Magento2 tarafında cookie sorunu da önüme geldi ( 06.08.2020 ) . https://github.com/Veriteworks/CookieFix adresinde bulacağınız modülü kurduğunuzda bu sorun kısmen çözülüyor. Ben sözkonusu modülü 2.3.4 ve 2.3.2 versiyonlarda denedim. Samesite=None işaretledi, ancak Secure parametresini işaretlemedi. Ben de biraz bodoslama çözdüm sorunu;
app/code/Veriteworks/CookieFix/Stdlib/Cookie/CookieManager.php satır 170 parametre değerini direkt true yaptım.

Aynı dosyada 199. satırı da aşağıdaki gibi true olarak değiştirdim.

Bu değişiklikler sonrası cookie Secure ve SameSite=None olarak işartlendi.

Eğer olur da sözkonusu eklenti kurulmaz ya da bir sorun olursa ( pek tavsiye edilen bir yöntem olmasa da ) core dosyada değişiklik yaparak da aynı sonuca ulaşabilirsiniz. vendor/magento/framework/Stdlib/Cookie/PhpCookieManager.php dosyası 141–149 satır arasını resimdeki gibi commentlayın. Hemen altına da şu kodu ekleyin;

$options = [
'expires' => $expire,
'path' => $this->extractValue(CookieMetadata::KEY_PATH, $metadataArray, ''),
'domain' => $this->extractValue(CookieMetadata::KEY_DOMAIN, $metadataArray, ''),
'secure' => true,
'httponly' => $this->extractValue(CookieMetadata::KEY_HTTP_ONLY, $metadataArray, false),
'samesite' => 'None',
];
$phpSetcookieSuccess = setcookie(
$name,
$value,
$options
);

Eğer üstteki kod hata verirse ya da php versiyonu 7.2 ise şu kodu kullanın;

$options = [
'expires' => $expire,
'path' => $this->extractValue(CookieMetadata::KEY_PATH, $metadataArray, ''),
'domain' => $this->extractValue(CookieMetadata::KEY_DOMAIN, $metadataArray, ''),
'secure' => true,
'httponly' => $this->extractValue(CookieMetadata::KEY_HTTP_ONLY, $metadataArray, false),
'samesite' => 'None',
];
if (PHP_VERSION_ID < 70300) {
$phpSetcookieSuccess = setcookie(
$name,
$value,
$options['expires'],
$options['path']."; samesite=None",
$options['domain'],
$options['secure'],
$options['expires']
);
}
else {
$phpSetcookieSuccess = setcookie(
$name,
$value,
$options
);
}

Edit 2 (06.04.2020) : Google Chrome geri adım attı, ve SameSite kısıtlaması ile alakalı değişikliği bir süreliğine geri aldığını duyurdu : https://blog.chromium.org/2020/04/temporarily-rolling-back-samesite.html

Edit 3 : 6 Nisanda yapılan geçici geri alma ile cookie değişikliği kaldırılmıştı ancak yaklaşık 1 ay sonra tekrar getirildi.

Kolay gelsin…

--

--