Masalah login terkait cookie yang tidak menentu


8

ini akan lama ...

Saya mendapat kasus buruk kegagalan login yang tidak menentu, karena manajemen cookie yang salah. Pertama-tama, saya mengelola toko tertutup (B2B) di mana pelanggan harus masuk sebelum mereka dapat melihat katalog. Setiap akses yang tidak terdaftar akan diarahkan ke halaman login, tetapi sesekali pelanggan tidak dapat login bahkan jika nama pengguna dan kata sandi benar. Saya mengatakan 'nama pengguna' karena saya menggunakan ekstensi Diglin_Username dan plugin StoreRestricition untuk mencapai perilaku yang diinginkan. Apa yang terjadi adalah bahwa kadang-kadang saya menemukan dua set cookie berbeda yang ditinggalkan oleh Magento, dan mereka merujuk pada dua domain yang berbeda (.www.abc.com dan .abc.com misalnya).

Setelah membaca artikel ini dari Alan Storm pada instantiasi awal sesi, dan menemukan cookie PHPSESSID yang ditakuti di browser saya, saya menyelidiki secara mendalam masalah ini.

Apa yang saya temukan adalah bermuka dua. Pertama saya meletakkan panggilan Mage :: Log () di fungsi start () di kelas Mage_Core_Model_Session_Abstract_Varien untuk mencatat berbagai upaya yang dilakukan oleh Magento untuk memulai sesi baru dan memperhatikan bahwa mengikuti Mage :: run () yang pertama memanggil preDispatch () , dispatch () dan metode postDispatch () dari kelas Mage_Core_Controller_Front_Action dipanggil dalam urutan yang biasa tetapi tampaknya ketika postDispatch () dijalankan tidak dapat menemukan sesi dimulai dengan preDispatch () dan melanjutkan untuk membuat sesi baru. Untuk hal ini saya menemukan perbedaan dalam kode antara versi Magento 1.7.x dan 1.8.x dan saya pikir itu mungkin bisa mengatasi masalah ini:

Magento 1.7.x - Mage_Core_Model_Session_Abstract_Varien kelas:

public function start($sessionName=null)
{
    if (isset($_SESSION)) {
        return $this;
    }
    .
    .
}

Magento 1.8.x - Mage_Core_Model_Session_Abstract_Varien kelas:

public function start($sessionName=null)
{
    if (isset($_SESSION) && !$this->getSkipEmptySessionCheck()) {
        return $this;
    }
    .
    .
}

Saya tidak bisa menemukan tempat untuk mengatur properti SkipEmptySessionCheck, jadi saya akhirnya menambal kelas Mage_Core_Controller_Front_Action dengan cara ini:

public function postDispatch()
{
    parent::postDispatch();
    if (!$this->getFlag('', self::FLAG_NO_START_SESSION )) {
        if (session_id()) {
            Mage::getSingleton('core/session')->setLastUrl(Mage::getUrl('*/*/*', array('_current'=>true)));
        }
    }
    return $this;
}

untuk memiliki postDispatch () tidak memanggil Mage :: getSingleton ('core / session') (yang akan membuat sesi baru) jika tidak dapat menemukan sesi sudah dimulai. Selama cookie PHPSESSID dan semua selesai, saya pikir ...

Tapi tidak demikian. Sekarang saya menyingkirkan cookie PHPSESSID tetapi masih kebagian dua cookie yang berbeda (tidak menentu) yang disimpan di browser. Hanya menghapus cookie yang salah, saya dapat berhasil login, atau saya diarahkan ke halaman login bahkan tanpa pesan. Saya mencoba untuk menyatakan domain cookie secara eksplisit dalam konfigurasi sistem tetapi ini tidak menyelesaikan masalah.

Jauh di dalam basis kode lagi, dan saya menemukan bahwa di berbagai tempat ketika Magento menetapkan cookie, diperlukan domain untuk digunakan dari fungsi getDomain () di kelas Mage_Core_Model_Cookie:

public function getDomain()
{
    $domain = $this->getConfigDomain();
    if (empty($domain)) {
        $domain = $this->_getRequest()->getHttpHost();
    }
    return $domain;
}

Sekarang, jika Anda melihat halaman yang Anda dapatkan dari Magento di browser Anda, Anda dapat menemukannya di bagian 'head' seperti ini:

<script type="text/javascript">
//<![CDATA[
Mage.Cookies.path     = '/';
Mage.Cookies.domain   = '.www.abc.com';
//]]>
</script>

Baris-baris ini berasal dari app / desain / frontend / base / default / template / halaman / js / cookie.phtml:

<script type="text/javascript">
//<![CDATA[
Mage.Cookies.path     = '<?php echo $this->getPath()?>';
Mage.Cookies.domain   = '<?php echo $this->getDomain()?>';
//]]>
</script>

dan pada gilirannya, kode ini merujuk fungsi getDomain () di kelas Mage_Page_Block_Js_Cookie:

public function getDomain()
{
    $domain = $this->getCookie()->getDomain();
    if (!empty($domain[0]) && ($domain[0] !== '.')) {
        $domain = '.'.$domain;
    }
    return $domain;
}

Jadi, jika saya menetapkan domain cookie dalam konfigurasi sistem sebagai, misalnya, 'www.abc.com', saya berakhir dengan:

Mage.Cookies.domain   = '.www.abc.com'

dan menemukan di cookie saya cookie 'www.abc.com' dan '.www.abc.com' saya pikir, "ok, saya akan menetapkan '.abc.com' di konfigurasi sistem dan akan selalu berakhir dengan ' cookie .abc.com !! "...

Tapi tidak mungkin. Sekarang di halaman HTML saya, saya selalu mendapatkan '.abc.com' tetapi meskipun demikian saya masih tidak menentu mendapatkan cookie 'www.abc.com' dan tanpa login.

Saya bingung, dan pelanggan saya mulai berpikir saya tidak sebagus yang dia kira (saya juga mulai berpikir ...) :(

Apakah beberapa dari kalian (dan cewek-cewek) punya beberapa petunjuk?

PEMBARUAN: Saya telah melihat seseorang mengaitkan masalah dengan sesi dan cookie dengan penggunaan Varnish sebagai cache untuk Magento. Karena saya menggunakan Varnish juga saya akan mencoba jika menonaktifkannya masalah ini dapat diselesaikan.


Hai Marius, mengapa hasil edit? Apakah saya melanggar beberapa aturan forum?
slamarca

kami melihat perilaku yang sama (sesi masuk dan kehilangan pelanggan), kecuali kami tidak dapat mereproduksi masalah dengan cara apa pun! Ini benar-benar mempersulit upaya pemecahan masalah, apalagi menyelesaikan masalah. Bagaimana Anda bisa mereplikasi masalah dengan andal? @Sandangkan Mangel - Itu masalahnya, saya belum bisa mereproduksi masalah ini jadi saya tidak bisa memastikan seperti apa cookie itu. Saya akan jauh lebih bahagia jika saya bisa memperbanyaknya sehingga saya bisa memverifikasi perbaikan yang dilakukan untuk menyelesaikan masalah. Saya berharap jika ada di antara Anda yang bisa mengarahkan saya ke arah yang benar tentang cara mereproduksi masalah ini. Terima kasih!

@Zhulak masalah yang sama dengan www. dan bukan www. kue?
Sander Mangel

Jawaban:


8

Ini adalah artikel dari NovusWeb: http://www.novusweb.com/fix-for-passing-magento-session-ids/

Perbaikan untuk Melewati ID Sesi Magento

Penulis: Brett Williams

Diposting 9 November 2011

Memperbaiki ID Sesi Magento

Kami sering menggunakan SSL bersama saat membangun situs e-commerce. Ini cara mudah hosting beberapa toko tanpa harus membeli sertifikat SSL terpisah untuk setiap situs. Sebagian besar klien e-commerce kami mengelola beberapa toko dalam satu instalasi Magento atau OpenCart. Baru-baru ini, kami menemukan masalah dengan Magento di mana ID sesi pelanggan tidak berhasil diloloskan antara kunjungan awal mereka ke situs dan tampilan halaman mereka setelah masuk ke toko sebagai pelanggan terdaftar. Magento tidak memberikan ID sesi yang sama, dan ini berarti bahwa pelanggan yang sebelumnya masuk dan menambahkan item ke troli mereka, akan kehilangan isi troli mereka setelah kembali nanti dan masuk. Bukan situasi yang hebat.

Saat melihat cookie yang dibuat selama sesi, saya menemukan bahwa ketika beralih dari domain tidak aman (yaitu, http: //) ke domain aman (yaitu, https: //), ID sesi telah berhasil diloloskan dan yang baru cookie untuk domain aman dibuat dengan ID sesi yang sama dengan domain tidak aman. Namun, ketika pelanggan masuk, cookie baru dibuat untuk domain aman dengan ID sesi yang sama sekali baru. Magento sekarang menggunakan cookie yang lebih baru, dan setiap kali pelanggan mengklik untuk kembali ke halaman domain tidak aman (misalnya halaman detail produk), mereka tidak lagi masuk ke Magento karena domain tidak aman menggunakan cookie / ID sesi, bukan yang baru ID sesi dibuat saat login. Solusinya adalah menemukan di mana ID sesi baru sedang dibuat dan mencegah hal itu terjadi.

Jadi, saya mulai menggali kode untuk melihat apakah saya bisa menemukan di mana Magento membuat sesi baru.

Dalam aplikasi / kode / inti / Penyihir / Pelanggan / Model / session.php, saya menemukan ini di baris 177-189 (Magento CE 1.5.1):

public function login($username, $password)
{
/** @var $customer Mage_Customer_Model_Customer */
$customer = Mage::getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId());

if ($customer->authenticate($username, $password)) {
    $this->setCustomerAsLoggedIn($customer);
    $this->renewSession();
    return true;
}
return false;
}

Solusi saya adalah mengomentari baris: $ this-> renewSession () :, sehingga Magento tidak akan membuat sesi baru ketika pelanggan masuk. Kode yang diubah terlihat seperti ini:

public function login($username, $password)
{
/** @var $customer Mage_Customer_Model_Customer */
$customer = Mage::getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId());

if ($customer->authenticate($username, $password)) {
    $this->setCustomerAsLoggedIn($customer);
    //$this->renewSession();
    return true;
}
return false;
}

Sejauh ini dalam pengujian kami, semuanya bekerja dengan baik, dan sesi pelanggan dipertahankan antara domain. Sekarang, sebelum Anda terburu-buru mengubah file inti ini, lakukan hal berikut:

Cadangkan basis data Anda (Anda harus selalu melakukan ini sebelum melakukan modifikasi). Bangun hierarki direktori berikut: app / code / local / Mage / Customer / Model /. Masukkan salinan session.php ke direktori baru ini. Komentari baris yang sesuai, yang ditunjukkan di atas, dan simpan file Anda. Dengan memasukkan modifikasi Anda ke direktori aplikasi / kode / lokal, Anda memberi tahu Magento untuk menggunakan file-file ini alih-alih file inti. Lebih penting lagi, Anda mencegah hilangnya modifikasi Anda jika Anda memperbarui Magento di masa depan.

Ini juga menyediakan cara mudah untuk menyimpan dan mengelola modifikasi kode Anda, karena Anda hanya perlu menyimpan file yang dimodifikasi di direktori app / code / local.

Pastikan untuk meninggalkan komentar jika Anda mengetahui solusi yang lebih elegan, atau jika Anda menemukan ini berhasil atau tidak bekerja untuk Anda.


4
Untuk modifikasi yang disimpan di app/code/local/Mage/*. Sebelum peningkatan Magento, ekstrak kode dari penginstal, bandingkan dengan kode yang Anda modifikasi untuk melihat apakah berbeda. Jika demikian, modifikasi versi baru untuk diterapkan setelah peningkatan. Tidak seperti mempertahankannya saat pemutakhiran agar situs terjatuh karena perubahan konten yang tidak kompatibel.
Fiasco Labs

3
Sepakat. Artikel ini hanya akan berlaku untuk pra pemasangan 1.8 karena mereka pindah $this->renewSession();ke setCustomerAsLoggedIn()fungsi.
seanbreeden

1
Untuk versi Magento terbaru, cukup cari "renewSession ()" dan Anda akan menemukannya di code/core/Mage/Core/Model/Session/Abstract.phpdan di code/core/Mage/Admin/Model/Session.phpmana itu dapat dikomentari. Dalam salinan model lokal, tentu saja. @FiascoLabs bahkan lebih baik, lakukan override yang tepat dari fungsi yang Anda perlu modifikasi, dan biarkan sisa file tetap dalam inti :)
WackGet

1
ini telah membantu kami keluar setelah 3 minggu mencoba memecahkan masalah, 4 tahun kemudian. Masalahnya terwujud bagi kami (Magento 1.9.3.2) ketika kami menginstal Amasty FPC dan memuat menguji server kami. yaitu tidak dapat masuk dengan Facebook dan / atau login normal, tidak dapat menambahkan ke troli ketika server sedang dimuat. Setelah itu, bahkan tanpa memuat masalah terwujud. Sekarang, sepertinya masalah itu sudah diperbaiki setelah mengikuti jawaban Anda. Terima kasih banyak @seanbreeden. Anda telah meniupkan kehidupan baru ke pengembang yang sangat lelah. <3
ali
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.