Panduan Pasukan Lucee MY

Sesi Lucee hilang atau berganda: punca sebenar

Sesi Lucee hilang selepas restart atau berganda di belakang proksi? Kenal pasti punca sebenar dan cara betulkan setClientCookies, sessionType dan cookie sesi.

Sesi Lucee hilang atau berganda: punca sebenar
0
Kandungan

Sesi Lucee hilang atau berganda: punca sebenar

Sesi Lucee hilang atau berganda hampir selalu berpunca daripada konfigurasi Application.cfc, bukan daripada kod halaman anda. Punca paling biasa ialah cookie sesi yang tidak dihantar, sesi yang disimpan dalam ingatan lalu hilang bila pelayan dimulakan semula, dan domain berbeza seperti www lawan apex yang menghasilkan dua sesi untuk satu pengguna. Artikel ini menunjukkan setiap punca dengan ujian sebenar yang dijalankan dalam Lucee 7.1.2.

Bagaimana sesi CFML dikenal pasti

Lucee mengenal pasti setiap pelawat melalui id sesi yang disimpan dalam cookie CFID dan CFTOKEN. Apabila sesi jenis cfml digunakan, nilai session.sessionid kelihatan seperti uji_sesi_03b02478-a832-4232-9c70-45de60871be0_0, iaitu gabungan nama aplikasi, satu UUID dan pengecam klien. Selagi cookie CFID dihantar balik pada setiap permintaan, Lucee memuatkan skop session yang sama dan semua nilai yang anda tulis kekal. Perbandingan penuh antara skop session, application dan request ada dalam panduan memahami scope CFML.

Sesi hilang selepas Lucee dimulakan semula

Ini punca nombor satu, dan ia bukan pepijat. Tetapan lalai this.sessionStorage ialah memory, yang bermaksud sesi disimpan hanya dalam ingatan JVM. Dokumentasi Lucee menyatakan secara terus untuk storan memory: sesi hanya disimpan dalam ingatan. Apabila Lucee dimulakan semula, sama ada untuk deploy kod baharu atau selepas but semula pelayan, semua sesi ingatan itu lenyap dan setiap pengguna dipaksa log masuk semula. Cara deploy tanpa memutuskan sesi dibincangkan dalam panduan deploy tanpa henti.

Sebab itu aplikasi yang tidak boleh kehilangan sesi semasa deploy memindahkan storan sesi ke pangkalan data atau cache, bukan ingatan. Butiran memilih storan ada dalam panduan pengurusan sesi. Saya tidak menguji but semula dalam rig kerana bekas ujian dikongsi dan tidak boleh dimulakan semula, tetapi kehilangan sesi selepas restart ialah akibat langsung storan memory yang disahkan daripada dokumentasi.

Tetapan this.setClientCookies mengawal sama ada Lucee menghantar cookie CFID dan CFTOKEN kepada pelayar. Lalai ialah Yes, tetapi sesetengah Application.cfc mematikannya atas sebab keselamatan yang salah faham. Dokumentasi menyatakan dengan jelas: jika ditetapkan No, Lucee tidak menghantar cookie CFID dan CFTOKEN secara automatik, dan anda mesti meletakkan CFID dan CFTOKEN pada URL untuk setiap halaman yang menggunakan sesi.

Berikut konfigurasi lengkap yang betul untuk satu pelayan, dan saya sahkan ia berjalan dalam Lucee 7.1.2:

component {
    this.name = "kedaiLucee";
    this.sessionManagement = true;
    this.sessionType = "cfml";
    this.sessionTimeout = createTimeSpan(0, 0, 30, 0);   // 30 minit
    this.applicationTimeout = createTimeSpan(1, 0, 0, 0); // 1 hari, lebih lama daripada sesi
    this.setClientCookies = true;                        // lalai, wajib hidup
    this.sessionCookie = {
        httpOnly: true,
        secure: false,          // tukar kepada true bila seluruh tapak HTTPS
        sameSite: "lax"
    };
}

Saya menguji kedua-dua keadaan setClientCookies dalam rig. Fail ujian ini membaca session.sessionid, menulis nilai session.kaunter, lalu mencetak kedua-duanya:

// Baca id sesi, tulis nilai, cetak semula.
session.kaunter = (session.kaunter ?: 0) + 1;
writeOutput("sessionid=" & session.sessionid & chr(10));
writeOutput("kaunter=" & session.kaunter & chr(10));

Dengan setClientCookies = true, cookie dihantar dan sesi kekal merentas permintaan. Dengan setClientCookies = false, tiada cookie dihantar dan setiap permintaan mendapat id sesi baharu. Perbandingan sebenar kedua-duanya dalam rig:

setClientCookies = true:
  Permintaan 1:  sessionid=uji_sesi_03b02478-a832-4232-9c70-45de60871be0_0  kaunter=1
  Permintaan 2:  sessionid=uji_sesi_03b02478-a832-4232-9c70-45de60871be0_0  kaunter=2
  Permintaan 3:  sessionid=uji_sesi_03b02478-a832-4232-9c70-45de60871be0_0  kaunter=3
  Set-Cookie: cfid=03b02478-a832-4232-9c70-45de60871be0; HttpOnly; SameSite=Lax

setClientCookies = false:
  Permintaan 1:  sessionid=uji_kod_3f1d5ae4-49eb-476b-b80e-ba7f9f0a8798_0  kaunter=1
  Permintaan 2:  sessionid=uji_kod_1ca25b83-bf4c-4594-abc1-22ca3d54e025_0  kaunter=1
  (tiada header Set-Cookie pada kedua-dua permintaan)

Kaunter kekal 1 kerana nilai ditulis ke sesi baharu yang berbeza setiap kali. Ini rupa sebenar sesi yang hilang, dan ia berpunca daripada satu baris konfigurasi, bukan daripada kod halaman. Butiran penuh Application.cfc ada dalam panduan memahami Application.cfc.

sessionType: cfml lawan j2ee

this.sessionType memilih siapa yang mengurus sesi. Nilai cfml bermakna Lucee mengurus sesi sepenuhnya, dan j2ee bermakna enjin servlet seperti Tomcat yang mengurusnya. Perbezaan yang kelihatan serta-merta ialah bentuk id sesi. Dengan cfml id sesi membawa nama aplikasi sebagai awalan, manakala dengan j2ee id sesi ialah JSESSIONID servlet:

sessionType = "cfml":  sessionid=uji_sesi_03b02478-a832-4232-9c70-45de60871be0_0
sessionType = "j2ee":  sessionid=8CDDAF2F35A9F7E860DB5BD959E38B4C   (cookie JSESSIONID)

Satu batasan penting yang dinyatakan dokumentasi: jenis j2ee tidak boleh menggunakan storan sesi. Jika anda merancang storan sesi dikongsi untuk kluster, anda mesti kekal pada jenis cfml. Saya menguji kedua-duanya dalam rig dan kedua-duanya mengekalkan sesi dengan betul, cuma identitinya berbeza.

sessionCookie: secure, httpOnly dan sameSite

this.sessionCookie ialah struktur yang mengawal bendera pada cookie CFID dan CFTOKEN. Kunci httpOnly menghalang JavaScript membaca nilai cookie, secure memastikan cookie hanya dihantar melalui HTTPS, dan sameSite menyekat cookie kepada konteks pihak pertama dengan nilai lax, strict atau none.

Perangkap sebenar di sini ialah secure = true digabungkan dengan halaman HTTP. Apabila cookie ditandakan secure, pelayar sebenar tidak akan menghantarnya melalui HTTP, jadi sesi kelihatan hilang pada halaman yang tidak menggunakan HTTPS. Dalam rig saya menetapkan secure kepada true dan melihat header Set-Cookie mengandungi bendera Secure dan HttpOnly, tetapi curl masih menghantar cookie balik melalui HTTP kerana curl menganggap 127.0.0.1 sebagai konteks selamat. Tingkah laku curl ini tidak mewakili pelayar sebenar, jadi saya tulis dengan jujur: bendera Secure disahkan wujud dalam header, tetapi kesan sebenar ke atas pelayar tidak dapat diuji dalam rig satu hos ini.

applicationTimeout lebih pendek daripada sesi

this.applicationTimeout menetapkan hayat skop application, dan this.sessionTimeout menetapkan hayat skop session. Kedua-duanya berkait: apabila skop application tamat, semua sesi di bawahnya turut mati kerana sesi tidak boleh hidup tanpa aplikasinya. Jika anda menetapkan applicationTimeout lebih pendek daripada sessionTimeout, pengguna kehilangan sesi lebih awal daripada yang anda jangkakan.

Dalam rig saya menetapkan applicationTimeout kepada 15 saat dan sessionTimeout kepada 30 minit, kemudian membiarkan aplikasi terbiar selama 88 saat. Sesi masih kekal dengan kaunter naik dari 1 hingga 6, yang menunjukkan Lucee tidak menyemak tamat masa aplikasi serta-merta, sebaliknya membersihkannya melalui tugas latar pada selang yang lebih panjang. Konsepnya tetap sah dan disahkan daripada dokumentasi, tetapi masa tepat pembersihan tidak boleh diramal daripada nilai applicationTimeout sahaja.

Sesi berganda di belakang proksi dan domain berbeza

Kadang-kadang sesi berganda bukan berpunca daripada kod langsung, tetapi daripada domain. Lalai this.setDomainCookies ialah No, yang bermaksud cookie CFID dan CFTOKEN ditetapkan untuk satu hos, bukan untuk seluruh domain. Akibatnya www.contoh.my dan contoh.my ialah dua hos berbeza dengan dua cookie berbeza. Pengguna yang melayari www kemudian berpindah ke apex akan mendapat sesi baharu, dan jika kedua-dua halaman masih aktif, anda melihat dua sesi untuk satu pengguna. Dokumentasi Lucee menasihatkan aplikasi yang berjalan dalam kluster supaya menetapkan setDomainCookies kepada Yes supaya cookie dikongsi merentas domain.

Di belakang proksi atau pengimbang beban, masalah yang sama muncul apabila sticky session dimatikan. Tanpa sticky session, permintaan pengguna boleh melantun antara dua pelayan, dan setiap pelayan yang tidak berkongsi storan sesi mencipta sesi sendiri. Hasilnya sesi berganda atau hilang bergantung kepada pelayan mana yang menjawab permintaan seterusnya.

Session cluster dan sticky session

Apabila aplikasi berjalan pada lebih daripada satu pelayan, this.sessionCluster menentukan bagaimana data sesi disegerakkan dengan storan. Dengan nilai false, iaitu lalai, ingatan tempatan ialah sumber utama dan storan hanya replika. Dengan nilai true, storan luaran menjadi sumber kebenaran dan disemak pada setiap permintaan. Tetapan ini diabaikan untuk storan jenis memory, jadi kluster sebenar memerlukan storan dikongsi seperti pangkalan data atau cache di samping sessionCluster. Tanpa kedua-duanya, sesi hilang setiap kali permintaan mendarat di pelayan yang berbeza. Panduan memilih storan untuk kluster dibincangkan dalam panduan pengurusan sesi.

Jadual gejala lawan punca

GejalaPunca sebenarPembetulan
Sesi hilang selepas restartsessionStorage memory, sesi dalam ingatanPindah storan ke datasource atau cache
Sesi berganda di belakang proksiTiada sticky session, storan tidak dikongsiDayakan sticky session dan storan dikongsi
Sesi hilang antara dua pelayansessionCluster false dengan storan memorysessionCluster true dan storan dikongsi
Cookie tidak dihantarsetClientCookies false atau secure true atas HTTPHidupkan setClientCookies, selaraskan HTTPS

Soalan Lazim

Kenapa sesi Lucee hilang selepas pelayan dimulakan semula?

Kerana storan lalai ialah memory, yang menyimpan sesi hanya dalam ingatan JVM. Bila pelayan dimulakan semula, ingatan itu dibuang dan semua sesi hilang. Pindahkan storan sesi ke pangkalan data atau cache untuk mengekalkannya.

Apa kesan setClientCookies false kepada sesi?

Lucee tidak menghantar cookie CFID dan CFTOKEN, jadi pelayar tidak menghantar identiti sesi balik pada permintaan seterusnya. Setiap permintaan mendapat sesi baharu dan semua nilai sesi kelihatan hilang.

Bagaimana cara membezakan sesi cfml dan j2ee?

Id sesi cfml membawa nama aplikasi sebagai awalan seperti uji_sesi_03b02478_0, manakala j2ee menggunakan JSESSIONID servlet. Jenis j2ee juga tidak boleh menggunakan storan sesi.

Kenapa pengguna mendapat dua sesi antara www dan apex?

Lalai setDomainCookies ialah No, jadi cookie ditetapkan per hos dan bukan per domain. www.contoh.my dan contoh.my mendapat cookie berbeza, lalu menghasilkan dua sesi. Tetapkan setDomainCookies kepada Yes untuk kluster.

Apa itu sticky session dan kenapa ia penting?

Sticky session memastikan pengimbang beban menghantar semua permintaan satu pengguna ke pelayan yang sama. Tanpanya, permintaan boleh mendarat di pelayan berbeza yang tidak berkongsi sesi, lalu sesi hilang atau berganda.

Sumber

0 komen

0 komen

Log masuk untuk menjawab atau memberi komen.

Log masuk