Sesi bersama selama CI3 dan Astro hidup berdampingan
Selama Fase 9, sebagian halaman masih dilayani CI3 dan sebagian sudah Astro. Kalau sesi keduanya tidak nyambung, pembaca akan ter-logout setiap kali menyeberang.
Intisari
- Isi
ci_sessions.dataadalah format serialisasi PHP, bukan JSON. Node tidak bisa membacanya tanpa parser khusus. - Tiga jalan: parser PHP di Node, tabel sesi kedua yang dibagi, atau memaksa login ulang sekali.
- Yang direkomendasikan: tabel sesi baru yang dibaca CI3 dan Astro. CI3 disunting sedikit, sekali.
- Nama cookie harus berbeda selama transisi supaya keduanya tidak saling menimpa.
- Apa pun jalannya, siapkan rencana untuk sesi yang ditinggalkan โ jangan biarkan menumpuk selamanya.
Kenapa ini masalah
Isi kolom ci_sessions.data:
__ci_last_regenerate|i:1756281600;member_id|i:4471;nama|s:11:"Budi Santos";
Ini format serialize() PHP. Node tidak punya padanan bawaannya.
Ditambah komplikasi: kalau CI3-mu memakai $config['sess_encrypt_cookie'] atau menyimpan sesi
di berkas alih-alih database, isinya bahkan tidak ada di MySQL sama sekali.
Tiga jalan keluar
| Parser PHP di Node | Tabel sesi bersama | Paksa login ulang | |
|---|---|---|---|
| Perubahan di CI3 | Tidak ada | Sedikit, sekali | Tidak ada |
| Perubahan di Astro | Parser + penulisan format PHP | Baca tabel baru | Tidak ada |
| Pembaca ter-logout | Tidak | Tidak | Ya, semuanya |
| Kerapuhan | Tinggi โ dua sistem menulis format yang sama | Rendah | Nol |
| Cocok kalau | Hampir tidak pernah | Migrasi bertahap | Peluncuran sekali jalan |
Jalur pertama terlihat paling elegan dan justru paling berbahaya. Membaca serialisasi PHP bisa dilakukan; menulisnya dari Node dengan cara yang tidak pernah membingungkan CI3 jauh lebih sulit. Dan bug di sini bukan bug tampilan โ ia bug sesi, yang berarti pembaca bisa mendapat sesi orang lain. Jangan tempuh jalur ini kecuali tidak ada pilihan.
Jalur yang direkomendasikan: tabel sesi bersama
Buat tabel sesi baru (bentuknya di materi sebelumnya), lalu ajari CI3 membacanya. Perubahan
di CI3 kecil dan dilakukan sekali.
// application/libraries/Sesi_bersama.php
class Sesi_bersama {
private $CI;
private $member = null;
public function __construct()
{
$this->CI =& get_instance();
$this->CI->load->database();
}
public function member()
{
if ($this->member !== null) return $this->member;
$id = $this->CI->input->cookie('__Host-sesi', TRUE);
if (!$id || strlen($id) !== 43) return $this->member = FALSE;
$row = $this->CI->db
->select('m.id, m.nama, m.email, m.peran')
->from('sesi s')
->join('member m', 'm.id = s.member_id')
->where('s.id', $id)
->where('s.kedaluwarsa >', date('Y-m-d H:i:s'))
->where('m.status', 'aktif')
->get()->row();
return $this->member = ($row ?: FALSE);
}
}
Lalu ganti $this->session->userdata('member_id') di CI3 dengan
$this->sesi_bersama->member()->id. Cari-ganti sekali, dan setelah itu kedua aplikasi
membaca sumber kebenaran yang sama.
Arah penulisannya penting: Astro yang menulis, CI3 yang membaca. Login dan logout dipindahkan ke Astro sejak awal โ itu halaman yang sederhana dan tidak banyak, jadi layak jadi yang pertama dimigrasikan. CI3 tidak perlu tahu cara membuat sesi sama sekali, cuma cara membacanya. Satu penulis, banyak pembaca, adalah rancangan yang jauh lebih sulit dirusak.
Nama cookie harus berbeda
CI3 : ci_session (biarkan, jangan disentuh)
Astro : __Host-sesi (baru)
Kalau keduanya memakai nama yang sama, siapa pun yang menulis terakhir menang, dan pembaca akan
ter-logout secara acak tergantung halaman mana yang terakhir dibuka. Biarkan ci_session tetap
ada dan diabaikan; ia akan mati sendiri saat CI3 dimatikan.
Masa transisi: memindahkan sesi yang sudah ada
Saat peluncuran, member yang sedang login punya ci_session tapi belum punya
__Host-sesi. Dua pilihan:
// Di CI3, saat member membuka halaman apa pun:
// kalau ia punya sesi CI3 tapi belum punya sesi baru, buatkan.
$member_id = $this->session->userdata('member_id');
if ($member_id && !$this->input->cookie('__Host-sesi')) {
$id = rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
$this->db->insert('sesi', [
'id' => $id,
'member_id' => $member_id,
'dibuat_pada' => date('Y-m-d H:i:s'),
'dipakai_pada' => date('Y-m-d H:i:s'),
'kedaluwarsa' => date('Y-m-d H:i:s', time() + 2592000),
]);
setcookie('__Host-sesi', $id, [
'expires' => time() + 2592000,
'path' => '/',
'secure' => TRUE,
'httponly' => TRUE,
'samesite' => 'Lax',
]);
}
random_bytes(), bukan rand() atau uniqid(). Ini pembuatan ID sesi โ
satu-satunya sumber acak yang boleh dipakai adalah yang kriptografis.
Jalankan jembatan ini selama beberapa minggu, lalu hapus. Setelah itu, member yang belum menyeberang tinggal login lagi seperti biasa.
Kalau kamu memilih memaksa login ulang
Ini pilihan yang sah, dan untuk portal dengan basis member kecil sering merupakan yang paling waras. Syaratnya: umumkan sebelumnya, dan pastikan alur "lupa password" bekerja sempurna di hari peluncuran โ karena sebagian orang akan lupa.
Yang tidak boleh: memaksa login ulang dan ternyata hash password-nya juga tidak bisa diverifikasi. Kombinasi itu berarti setiap member harus reset password lewat email di hari yang sama โ dan penyedia emailmu akan menganggap lonjakan itu sebagai spam lalu memblokirnya. Selesaikan materi password lebih dulu.
Setelah CI3 dimatikan
-- Pastikan tidak ada lagi yang menulis ke sana
SELECT MAX(FROM_UNIXTIME(timestamp)) FROM ci_sessions;
-- Kalau sudah lewat beberapa minggu tanpa aktivitas:
DROP TABLE ci_sessions;
Latihan: periksa konfigurasi sesi CI3-mu sekarang โ sess_driver,
sess_save_path, dan apakah sess_encrypt_cookie aktif. Kalau drivernya
files, catat itu: berarti sesi tidak ada di database sama sekali dan jalur "parser PHP"
otomatis gugur. Lalu tulis library Sesi_bersama di CI3-mu dan buktikan ia bisa membaca sesi
yang dibuat Astro.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.