Data pemindahan Php antara sesi. Fungsi untuk mengakses sesi. Contoh kerja sesi

Fungsi Akses Sesi

Sokongan sesi dalam PHP ialah cara menyimpan data khusus merentas akses berjujukan. Ini membolehkan anda membuat aplikasi yang lebih khusus dan meningkatkan daya tarikan tapak web anda.

Jika anda sudah biasa dengan mengekalkan sesi dengan PHPLIB, anda akan mendapati bahawa beberapa isu adalah serupa dengan mengekalkan sesi dalam PHP.

Pelawat ke tapak anda diberikan id unik, yang dipanggil id sesi. Ia disimpan dalam kuki di sisi pengguna atau disuntik ke dalam URL.

Sokongan sesi memberi anda keupayaan untuk mendaftarkan bilangan pembolehubah sewenang-wenangnya dan menyimpannya di antara pelaksanaan pertanyaan. Apabila pengguna memasuki tapak anda, PHP akan sama ada secara automatik (jika session.auto_start ditetapkan kepada 1) atau atas permintaan anda (secara eksplisit - melalui session_start() atau secara tersirat - melalui session_register()) semak sama ada id sesi tertentu telah dihantar bersama dengan permintaan. Jika ya, persekitaran sebelumnya dicipta semula.

Semua pembolehubah berdaftar disirikan selepas permintaan tamat. Pembolehubah tidak ditentukan yang didaftarkan ditandakan sebagai tidak ditentukan. Pada permintaan seterusnya ia tidak ditentukan oleh modul sesi melainkan pengguna mentakrifkannya kemudian.

Menggunakan $_SESSION (atau $HTTP_SESSION_VARS dalam PHP 4.0.6 atau lebih awal) disyorkan atas sebab keselamatan dan kebolehbacaan kod. Jika terdapat pembolehubah $_SESSION atau $HTTP_SESSION_VARS, tidak perlu menggunakan fungsi session_register()/session_unregister()/session_is_registered(). Pengguna boleh mengakses pembolehubah sesi sebagai pembolehubah biasa.

Contoh 2: Menyahdaftar pembolehubah menggunakan $_SESSION

session_start();
// Gunakan $HTTP_SESSION_VARS dengan PHP 4.0.6 atau kurang
unset($_SESSION [ "count" ]);
?>
Perhatian!

Jika anda menggunakan $HTTP_SESSION_VARS / $_SESSION dan telah dilumpuhkan register_globals, jangan gunakan session_register() , session_is_registered() Dan session_unregister() .

Parameter URL

Model sesi menyokong kedua-dua kaedah. Kuki adalah optimum, tetapi kerana ia tidak selamat (pelanggan mungkin tidak menerimanya), kami tidak boleh bergantung padanya. Kaedah kedua membenamkan id sesi terus dalam URL.

PHP dapat melakukan ini secara telus apabila disusun dengan pilihan --enable-trans-sid. Jika anda mendayakan pilihan ini, URI relatif akan berubah untuk memasukkan id sesi secara automatik. Sebagai alternatif, anda boleh menggunakan pemalar SID, yang ditakrifkan jika pelanggan tidak menghantar kuki yang sepadan. SID adalah dalam bentuk session_name=session_id atau rentetan kosong.

Catatan: Arahan arg_separator.output php.ini membolehkan anda mengkhususkan pemisah hujah.

Contoh berikut menunjukkan cara mendaftar pembolehubah dan cara menghubungi halaman lain dengan betul menggunakan SID.

Contoh 5: Mengira bilangan log masuk untuk pengguna individu

jika (! session_is_registered ("count")) (
session_register("count");
$kira = 1;
) lain (
$count++;
}
?>

Hello pengunjung, anda telah melihat halaman inikali.

Untuk meneruskan, ">klik
di sini.

SID?> tidak diperlukan jika --enable-trans-sid digunakan semasa menyusun PHP.

Catatan: Diandaikan bahawa URL bukan relatif menghala ke tapak luaran dan oleh itu tidak melampirkan SID, kerana terdapat risiko membocorkan maklumat SID ke pelayan lain.

Untuk melaksanakan penyimpanan pangkalan data atau kaedah lain yang anda perlu gunakan session_set_save_handler() untuk mencipta satu set fungsi storan peringkat pengguna.

Konfigurasi

Mari lihat arahan konfigurasi lalai:

Nama arahan Nilai asal Nota
session.save_path ""
sesi.nama "PHPSESSID"
session.save_handler "fail"
session.auto_start "0"
session.gc_probability "1"
session.gc_divisor "100" Tersedia daripada PHP 4.3.2.
session.gc_maxlifetime "1440"
session.serialize_handler "php"
session.cookie_lifetime "0"
session.cookie_path "/"
session.cookie_domain ""
session.cookie_secure "" Tersedia daripada PHP 4.0.4.
session.use_cookies "1"
session.use_only_cookies "0" Tersedia daripada PHP 4.3.0.
sesi.pemeriksa_perujuk ""
session.entropy_file ""
session.entropy_length "0"
session.cache_limiter "nocache"
session.cache_expire "180"
session.use_trans_sid "0" Tersedia daripada PHP 4.0.3.
session.bug_compat_42 "1" Tersedia daripada PHP 4.3.0.
session.bug_compat_warn "1" Tersedia daripada PHP 4.3.0.
session.hash_function "0" Tersedia daripada PHP 5.0.0.
session.hash_bits_per_character "4" Tersedia daripada PHP 5.0.0.
url_rewriter.tags "a=href,area=href,frame=src,form=,fieldset=" Tersedia daripada PHP 4.0.4.

Sistem pengurusan sesi menyokong beberapa pilihan konfigurasi yang boleh anda letakkan dalam fail php.ini anda. Kami akan memberikan gambaran ringkas.

    session.save_handler menentukan nama pengendali untuk menyimpan dan meminta data yang dikaitkan dengan sesi. Secara lalai fail .

    session.save_path menentukan hujah yang dihantar untuk menyimpan pengendali. Jika anda memilih pengendali fail lalai, ini akan menjadi laluan ke mana fail dibuat. Lalai ialah /tmp. Jika kedalaman laluan untuk session.save_path lebih besar daripada 2, kutipan sampah tidak akan berlaku.

    session.name menentukan nama sesi, yang digunakan sebagai nama kuki. Ia mesti mengandungi hanya huruf dan nombor. Lalai ialah PHPSESSID.

    session.auto_start menentukan sama ada modul sesi memulakan sesi secara automatik pada permintaan mula. Lalai ialah 0 (dilumpuhkan).

    session.cookie_lifetime menentukan tempoh penyimpanan kuki dalam beberapa saat. Nilai 0 bermaksud "sehingga penyemak imbas ditutup." Lalai ialah 0.

    session.serialize_handler mentakrifkan nama pengendali untuk siri/deserialisasi data. Pada masa ini format PHP dalaman (nama php) dan WDDX (nama wddx) disokong. WDDX hanya tersedia apabila PHP disusun dengan sokongan WDDX. Secara lalai php.

    session.gc_probability menentukan peratusan kebarangkalian bahawa utiliti gc (kutipan sampah) akan bermula pada setiap permintaan. Lalai ialah 1.

    session.gc_maxlifetime menentukan bilangan saat selepas itu data akan dianggap "sampah" dan dikosongkan.

    session.referer_check mengandungi subrentetan yang boleh anda semak pada setiap permintaan HTTP. Jika permintaan telah dihantar oleh pelanggan dan subrentetan tidak ditemui, id sesi terbenam akan ditandakan sebagai tidak sah. Lalai ialah rentetan kosong.

    session.entropy_file menentukan laluan ke sumber luaran (fail) yang akan digunakan sebagai sumber tambahan dalam proses mencipta id sesi. Contoh: /dev/random atau /dev/urandom, yang tersedia pada banyak sistem Unix.

    session.entropy_length menentukan bilangan bait yang akan dibaca daripada fail yang dinyatakan di atas. Lalai ialah 0 (dilumpuhkan).

Semasa anda terus mempelajari PHP, anda mungkin akan menggunakan ciri seperti sesi, atau mendengarnya dari semasa ke semasa. Dalam artikel ini saya akan bercakap tentang mereka dengan lebih terperinci dan menggunakan contoh ilustrasi untuk menganalisis prinsip operasi mereka. Saya juga akan memberitahu anda di mana dan cara ia biasanya boleh digunakan.

Apakah sesi? Sesi membolehkan anda membuat sejenis sambungan antara tapak itu sendiri dan pengguna menggunakan pengecam sesi. Semua pembolehubah sesi dan nilainya disimpan secara eksklusif pada pelayan. Pengguna, serta pelayan, hanya menyimpan pengecam sesi, yang dijana secara rawak; mereka dengan tepat membenarkan sambungan pelayan-pelanggan ini diwujudkan.

ID sesi yang disimpan pada bahagian klien (pada komputernya) ialah fail biskut. Kuki disimpan dalam penyemak imbas pengguna, tetapi fail yang sepadan juga dibuat pada pelayan.

Jom terus berlatih.

Buat sesi:

Cara paling asas di sini ialah menggunakan fungsi session_start:

1 2 // Mulakan sesi session_start();

// Mulakan sesi session_start();

Fungsi ini menyemak sama ada terdapat pengecam sesi; jika ia tidak wujud, ia menciptanya. Dan jika ia tersedia, maka ia memuatkan pembolehubah berdaftar dari sesi sedia ada.

Binaan ini hanya perlu dipanggil sekali setiap halaman dan sebelum sebarang output (peraturan ini juga digunakan untuk setcookie()).

Biar saya berikan anda contoh: apabila sesi dibuat dalam penyemak imbas, kuki di sana kelihatan seperti ini:

Apabila sesi dibuat, kuki berikut dihantar ke penyemak imbas:

1 2 bergema "Nama sesi:". session_name(). "ID Sesi: ". session_id(); // Nama sesi: PHPSESSID ID Sesi: mceu371l97id3sa0vcbjqnht06

echo "Nama sesi: ".session_name(). " ID Sesi: ".session_id(); // Nama sesi: PHPSESSID ID Sesi: mceu371l97id3sa0vcbjqnht06

Mari buat pembolehubah sesi:

Pembolehubah sesi boleh dibuat dengan menambahkan beberapa nilai pada elemen superglobal tatasusunan $_SESSION:

unset($_SESSION["log masuk"]);

Kaedah di atas adalah baik, tetapi anda boleh mengosongkan keseluruhan tatasusunan $_SESSION, dengan itu mengalih keluar semua pembolehubah daripada sesi:

1 2 // Bersihkan tatasusunan $_SESSION kami$_SESSION = tatasusunan () ;

// Kosongkan tatasusunan kami $_SESSION $_SESSION = array();

2. Sekarang kita perlu membatalkan kuki (di mana nama sesi dirujuk semasa mengakses id sesi dalam kuki dan URL):

1 2 3 jika (isset ($_COOKIE [ session_name () ] ) ) ( // session_name() - tarik keluar nama sesi semasa setcookie (nama_sesi () , "" , masa () - 86400 , "/"); )

if (isset($_COOKIE)) ( // session_name() - tarik keluar nama sesi semasa setcookie(session_name(), "", time()-86400, "/"); )

3. Nah, seterusnya kita akan memusnahkan sesi (tutupnya):

session_start(); ob_start();

Berikut ialah contoh kod yang lebih terperinci menggunakan kod dan fungsi yang dibincangkan sebelum ini:

1 2 3 4 5 6 7 8 9 if (isset ($_SESSION [ "log masuk" ] ) ) ( echo "Hello, " . $_SESSION [ "nama" ] . " " ; unset ($_SESSION [ "log masuk" ] ) ; if (isset ($_COOKIE [ session_name () ] ) ) (setcookie (nama_sesi () , "" , masa () - 86400 , "/"); // kandungan sesi kami ialah rentetan kosong) ob_end_flush () ; // Hantar output ke penyemak imbas session_destroy();

if (isset($_SESSION["log masuk"])) ( echo "Hello, " . $_SESSION["name"] . " "; unset ($_SESSION["log masuk"]); if (isset($_COOKIE)) ( setcookie(session_name(), "", time()-86400, "/"); // kandungan sesi kami ialah rentetan kosong ) ob_end_flush(); // Hantar output ke pelayar session_destroy();

Walau bagaimanapun, perlu diingat bahawa menggunakan fungsi ob_end_flush() tidak selalu diperlukan. Dan semuanya kerana penterjemah PHP secara automatik mengosongkan penimbal anda apabila melaksanakan beberapa skrip.

Mari cipta semula pengecam sesi:

Setiap kali anda log masuk ke sistem, atas sebab keselamatan, adalah perlu untuk mencipta semula pengecam sesi. Semua maklumat dalam pembolehubah sesi anda disimpan pada pelayan web anda dalam bentuk teks biasa dalam fail tertentu, semua maklumat tentang pembolehubah yang digunakan dalam sesi disimpan dan hanya pengecam sesi berubah. Untuk menjana semula pengecam sesi, gunakan fungsi session_regenerate_id(), kemudian, setelah selesai, muat semula halaman sedia ada atau hantar pengguna ke halaman lain menggunakan ubah hala.

Cara sesi berfungsi:

Dalam tangkapan skrin di bawah anda boleh melihat gambaran keseluruhan ringkas mekanisme sesi itu sendiri.

Mari kita kurangkan jangka hayat sesi:

Nilai seumur hidup sesi standard ialah 0, iaitu, jika pengguna menutup tetingkap penyemak imbas, sesi juga akan ditutup. Tetapi kadangkala terdapat keperluan untuk memusnahkan sesi pelanggan secara paksa selepas beberapa waktu berlalu, contohnya kerana ketidakaktifan di pihaknya di tapak. Mari kita lihat kaedah pelaksanaan sedemikian menggunakan contoh kebenaran pengguna: kami akan mencipta beberapa jenis pembolehubah dan menyimpan di dalamnya masa yang digunakan semasa kebenaran pengguna, contohnya, jika pengguna cuba menavigasi halaman, maka kami membandingkan masa dengan masa dia tidak aktif, dan jika melebihi had ini, dia akan dilog keluar dan dihantar ke halaman kebenaran.

1 2 3 4 5 6 7 8 $_SESSION["start"] = masa(); // Mula masa apabila pengguna log masuk$timezon = masa () ; // Kali ini (yang wujud sekarang)$time_limit = 2000 ; // Ini adalah masa maksimum pengguna tidak aktif if ($timezon > $_SESSION [ "start" ] + $time_limit ) ( echo "Masa sudah tamat"; ) else ($_SESSION [ "mula" ] = masa () ; ) // jika semuanya baik, kemas kini

$_SESSION["start"] = masa(); // Mula masa apabila pengguna log masuk $timezon= time(); // Kali ini (yang wujud sekarang) $time_limit = 2000; // Ini adalah masa maksimum pengguna tidak aktif jika ($timezon> $_SESSION["start"] + $time_limit) ( echo "Masa telah tamat"; ) else ($_SESSION["start"] = time(); ) // jika semuanya baik, mari kemas kini

Kadang-kadang orang mempunyai soalan "Bagaimana untuk melaksanakan seumur hidup sesi tak terhingga?", di sini saya akan berikan jawapannya. Ini tidak sepatutnya dilakukan, ia pada asasnya salah dengan idea itu. Sesi itu dibuat untuk tujuan pengguna melawat tapak - ia dibuka, dia pergi - ia ditutup (dimusnahkan). Apabila dia log masuk semula, sesi baru dibuka. Walau bagaimanapun, anda boleh menggunakan data daripada kuki untuk sesi tersebut, yang boleh disimpan untuk masa yang agak lama, contohnya, apabila menggunakan kotak semak "Ingat saya" (Ingat yang ada di tapak web?)...

Menggunakan sesi dengan kuki dilumpuhkan:

Beritahu saya ini tidak berlaku? Malangnya, ini kadang-kadang berlaku. Contohnya, jika kami menetapkan tetapan session.use_trans_sid kepada 1, maka jika tiada kuki, PHP akan lulus parameter PHPSESSID menggunakan kaedah GET dalam baris permintaan anda.

Itu sahaja, artikel sudah selesai. Jika anda masih mempunyai soalan mengenai penggunaan sesi, atau mungkin mempunyai sebarang penambahan atau ulasan, anda boleh meninggalkan segala-galanya dalam ulasan untuk artikel ini.

Pengendalian sesi ialah teknik utama dalam PHP yang membolehkan data pengguna disimpan di semua halaman tapak web atau aplikasi. Dalam artikel ini anda akan mempelajari asas pengendalian sesi dalam PHP.

Kami akan mulakan dengan menerangkan cara sesi berfungsi dan cara ia berkaitan dengan kuki. Kemudian kita akan melihat beberapa coretan kod yang menunjukkan cara bekerja dengan sesi. Anda akan belajar cara mencipta dan memusnahkan sesi dan cara menukar pembolehubah sesi.

Apakah sesi dalam PHP?

Sesi ialah mekanisme untuk menyimpan maklumat merentasi halaman web untuk mengenal pasti pengguna semasa mereka menavigasi tapak atau aplikasi. Adakah anda tertanya-tanya mengapa sesi diperlukan untuk tapak web? Untuk memahami sebab sesi diperlukan, kita perlu kembali sedikit dan melihat cara protokol HTTP berfungsi.

Protokol HTTP ialah protokol tanpa kewarganegaraan, yang bermaksud bahawa pelayan tidak boleh memadankan pengguna tertentu merentas berbilang permintaan. Sebagai contoh, apabila mengakses halaman web, pelayan bertanggungjawab untuk menyediakan kandungan halaman yang diminta. Jadi apabila anda mengakses halaman lain di tapak web yang sama, pelayan web mentafsir setiap permintaan secara berasingan, seolah-olah ia tidak berkaitan antara satu sama lain. Pelayan tidak tahu bahawa setiap permintaan datang dari pengguna yang sama.

Gambar rajah berikut secara ringkas menggambarkan protokol HTTP.

Dalam model ini, jika anda ingin memaparkan maklumat pengguna, anda perlu mengesahkan pengguna pada setiap permintaan. Bayangkan jika anda perlu memasukkan nama pengguna dan kata laluan anda pada setiap halaman data anda! Ya, ini akan menyusahkan dan secara amnya tidak praktikal, dan di sinilah sesi datang untuk menyelamatkan.

Sesi membolehkan anda bertukar maklumat antara halaman berbeza pada tapak atau aplikasi yang sama, dan membantu mengekalkan keadaan. Ini membolehkan pelayan mengetahui bahawa semua permintaan datang daripada pengguna yang sama, membolehkan tapak memaparkan maklumat dan pilihan pengguna.

Mengendalikan log masuk dengan sesi dan kuki

Mari lihat dengan cepat contoh log masuk tapak web biasa untuk memahami perkara yang berlaku di sebalik tabir.

  1. Pengguna membuka halaman log masuk laman web.
  2. Selepas menyerahkan borang log masuk, pelayan di hujung yang satu lagi mengesahkan permintaan dengan menyemak bukti kelayakan yang dimasukkan.
  3. Jika bukti kelayakan yang dimasukkan oleh pengguna adalah betul, pelayan mencipta sesi baharu. Pelayan menjana nombor rawak unik yang dipanggil ID sesi. Juga, fail baharu dicipta pada pelayan, yang digunakan untuk menyimpan maklumat yang berkaitan dengan sesi.
  4. Kemudian, ID sesi diserahkan kembali kepada pengguna, bersama-sama dengan apa sahaja yang dimintanya. Di sebalik tabir, ID sesi ini dihantar dalam pengepala respons kuki PHPSESSID (itulah yang dipanggil secara lalai).
  5. Apabila penyemak imbas menerima respons daripada pelayan, ia menerima pengepala kuki PHPSESSID. Jika penyemak imbas anda membenarkan kuki, ia akan menyimpan PHPSESSID ini, yang menyimpan ID sesi yang dihantar oleh pelayan.
  6. Untuk permintaan seterusnya, kuki PHPSESSID dihantar kembali ke pelayan. Apabila pelayan menerima kuki PHPSESSID, ia cuba untuk memulakan sesi dengan ID sesi tersebut. Ia melakukan ini dengan memuatkan fail sesi yang dibuat lebih awal semasa permulaan sesi. Ia kemudiannya memulakan pembolehubah tatasusunan superglobal $_SESSION dengan data yang disimpan dalam fail sesi.

Dengan cara ini, data pengguna dikekalkan walaupun merentasi berbilang permintaan dan pengguna tidak hilang sepanjang keseluruhan sesi.

Rajah berikut menunjukkan cara protokol HTTP berfungsi dengan sesi.

Memandangkan anda telah melihat pengenalan ringkas tentang cara sesi berfungsi, kami akan mencipta beberapa contoh praktikal untuk menunjukkan cara membuat dan memanipulasi pembolehubah sesi.

Bagaimana untuk memulakan sesi

Dalam bahagian ini, kita akan membincangkan cara memulakan sesi dalam PHP.

Pada bila-bila masa anda ingin bekerja dengan pembolehubah sesi, anda perlu memastikan bahawa sesi sudah berjalan. Sesi dalam PHP boleh dimulakan dalam beberapa cara.

Menggunakan fungsi session_start

Kaedah di mana sesi dimulakan dengan fungsi session_start ialah sesuatu yang sering anda lihat.

Adalah penting bahawa fungsi session_start dipanggil pada permulaan skrip, sebelum menghantar apa-apa ke penyemak imbas. Jika tidak, anda akan menghadapi ralat Pengepala sudah dihantar yang terkenal.

Sesi automatik bermula

Jika anda perlu menggunakan sesi dalam aplikasi anda, anda boleh memulakan sesi secara automatik tanpa menggunakan fungsi session_start.

Dalam fail php.ini Terdapat parameter session.auto_start yang membolehkan anda memulakan sesi secara automatik untuk setiap permintaan. Nilai lalai ialah 0 (mati), dan anda boleh menetapkannya kepada 1 (hidup) untuk mendayakan ciri mula automatik.

Session.auto_start = 1

Sebaliknya, jika anda tidak mempunyai akses kepada fail php.ini dan anda menggunakan pelayan web Apache, pembolehubah ini boleh ditetapkan menggunakan fail .htaccess.

Php_value session.auto_start 1

Jika anda menambah baris di atas pada anda .htaccess fail, maka ini akan melancarkan sesi secara automatik dalam aplikasi PHP anda.

Bagaimana untuk mendapatkan ID sesi

Seperti yang kita bincangkan sebelum ini, pelayan mencipta nombor unik untuk setiap sesi baharu. Jika anda ingin mendapatkan ID sesi, anda boleh menggunakan fungsi session_id seperti yang ditunjukkan dalam coretan berikut.

Ini sepatutnya memberi anda ID sesi semasa. Fungsi pengecam session_id adalah menarik kerana ia juga boleh mengambil satu hujah - pengecam sesi. Jika anda ingin menggantikan ID sesi yang dijana sistem dengan anda, anda boleh berbuat demikian dengan menghantar argumen pertama ke fungsi session_id.

Adalah penting untuk ambil perhatian bahawa jika anda ingin memulakan sesi menggunakan ID sesi anda, fungsi session_id mesti hadir sebelum panggilan session_start.

Mencipta Pembolehubah Sesi

Dalam bahagian ini, kita akan belajar bagaimana untuk memulakan pembolehubah sesi dalam PHP.

Seperti yang telah kita bincangkan, apabila sesi dimulakan, tatasusunan superglobal $_SESSION dimulakan dengan maklumat sesi yang sepadan. Secara lalai, ia dimulakan sebagai tatasusunan kosong dan anda boleh menyimpan lebih banyak maklumat menggunakan pasangan nilai kunci.

Mari lihat contoh kod berikut, yang menunjukkan cara untuk memulakan pembolehubah sesi.

Seperti yang anda lihat, kami memulakan sesi pada permulaan skrip menggunakan fungsi session_start. Selepas ini, kami memulakan beberapa pembolehubah sesi. Akhir sekali, kami menggunakan pembolehubah ini melalui pembolehubah superglobal $_SESSION.

Apabila menyimpan data sesi menggunakan $_SESSION , ia akhirnya disimpan dalam fail sesi yang sepadan pada pelayan yang dibuat semasa sesi dimulakan. Dengan cara ini, data sesi dikongsi antara berbilang permintaan.

Seperti yang telah kita lihat, maklumat sesi dihantar bersama-sama dengan permintaan, jadi pembolehubah sesi yang dimulakan pada satu halaman boleh diakses pada halaman lain, dan juga sehingga akhir sesi. Sebagai peraturan, sesi tamat tempoh apabila penyemak imbas ditutup.

Cara menukar dan memadam pembolehubah sesi

Anda boleh mengubah suai atau memadam pembolehubah sesi yang sebelum ini dibuat dalam aplikasi anda, sama seperti pembolehubah PHP biasa.

Mari lihat cara menukar pembolehubah sesi.

Dalam kod di atas, kami menyemak untuk melihat sama ada pembolehubah $_SESSION["count"] ditetapkan. Jika tidak ditetapkan, kita tetapkan kepada 1, jika tidak, kita tambahkan sebanyak 1. Jadi, jika anda memuat semula halaman ini beberapa kali, anda sepatutnya melihat kaunter meningkat sebanyak satu setiap kali!

Sebaliknya, jika anda ingin mengalih keluar pembolehubah sesi, anda boleh menggunakan fungsi tidak ditetapkan seperti yang ditunjukkan dalam coretan berikut.

Oleh itu, anda tidak lagi dapat mengakses pembolehubah $_SESSION["log_in_user_id"] kerana ia telah dialih keluar oleh fungsi yang tidak ditetapkan. Inilah cara anda boleh menukar maklumat sesi.

Bagaimana untuk memusnahkan sesi

Dalam bahagian ini, kita akan melihat bagaimana kita boleh memusnahkan sesi. Dalam bahagian sebelumnya, kami melihat fungsi tidak ditetapkan, yang digunakan untuk mengalih keluar pembolehubah sesi tertentu. Sebaliknya, jika anda ingin memadam semua data yang dikaitkan dengan sesi sekaligus, anda boleh menggunakan fungsi session_destroy.

Mari cuba fahami cara ini berfungsi dalam contoh berikut.

Fungsi session_destroy memadam semua yang disimpan dalam sesi semasa. Oleh itu, dengan permintaan seterusnya anda akan melihat pembolehubah $_SESSION kosong kerana data sesi yang disimpan pada cakera telah dipadamkan oleh fungsi session_destroy.

Biasanya, fungsi session_destroy harus digunakan apabila pengguna log keluar.

Kesimpulan

Dalam artikel ini, kami mempelajari asas pengendalian sesi dalam PHP. Ini adalah konsep utama yang membolehkan anda menyimpan maklumat untuk halaman web.

Pada separuh pertama artikel, kami membincangkan konsep asas sesi, dan kemudian kami mencipta beberapa contoh dalam PHP untuk menunjukkan cara anda boleh mencipta dan memusnahkan sesi, dan memanipulasi pembolehubah sesi.

Sesi ialah mekanisme yang membolehkan anda menyimpan data tertentu pada pelayan, unik untuk setiap pengguna. Pembaca yang prihatin terutamanya akan melihat persamaan dengan biskut. Dan, secara umum, ia adalah perkara yang sama. Walau bagaimanapun, perkara utama: data tidak disimpan dalam pelayar pengguna, tetapi dalam fail khas pada pelayan, yang namanya unik untuk setiap pengguna. Unik ID sesi PHP sudah disimpan dalam biskut.

Jom ikut awak Mari kita bekerja dengan sesi dalam PHP. Dan mari kita mulakan dengan session_start() fungsi. Fungsi ini melakukan perkara berikut: jika pengguna log masuk buat kali pertama, ia mencipta pengecam unik dan menulisnya ke biskut, dan juga mencipta fail baharu, sekali lagi unik kepada pengguna. Jika pengguna telah log masuk, maka pelayan membaca nilai pengecam unik daripada biskut dan, selaras dengannya, mengakses fail sesi yang diperlukan. Daripada fail ini PHP membaca semua data dan memasukkannya ke dalam tatasusunan $_SESSION. Mari kita tulis kod ringkas di mana kita menulis pembolehubah pada sesi, atau membacanya jika ia telah ditulis.

session_start();
if (isset($_SESSION["nama"])) $name = $_SESSION["nama"];
lain $_SESSION["nama"] = "15St";
echo $nama;
?>

Mula-mula kita panggil fungsi session_start(). yang saya terangkan di atas. Kemudian kami menyemak sama ada pembolehubah "wujud" nama" dalam sesi. Jika ia wujud, maka kami membaca data daripadanya dan menulisnya kepada pembolehubah nama. Jika ia tidak wujud (iaitu, pengguna datang buat kali pertama), kemudian tetapkan pembolehubah " nama"dalam nilai sesi" 15Hb.". Baris seterusnya memaparkan nilai pembolehubah $nama. Jelas sekali, kali pertama anda menjalankannya, anda akan melihat baris kosong, tetapi kali kedua anda menjalankannya, anda akan melihat baris " 15Hb.", baca dari sesi itu.

Saya menasihati anda untuk memasukkan dalam bar alamat sekarang: " javascript:document.cookie" (masuk pada tab yang sama semasa anda menjalankan skrip). Akibatnya, anda akan melihat sesuatu seperti ini: " PHPSESSID=". Maksudnya saja PHPSESSID dan dengan itu merupakan pengecam unik.

Dan untuk membuat semuanya benar-benar jelas, saya menasihati anda untuk mencari fail sesi. Jika anda menggunakan Denwer, maka ia berada dalam folder " tmp". Lihat fail yang bermula dengan " sess_"- ini adalah mereka fail sesi. Anda boleh membukanya dalam pad nota ringkas.

Satu lagi harta yang sangat penting ialah Temporal sesi dalam PHP. Kemudian jika biskut disimpan sehingga ia dipadamkan oleh penyemak imbas. Dan penyemak imbas tidak pernah memadamkannya secara lalai. Kemudian sesi disimpan untuk masa yang dinyatakan dalam Tetapan PHP. Secara lalai, ini adalah 15 minit. Iaitu, jika anda menggunakan pengesahan berasaskan sesi, kemudian selepas 15 minit tidak bertindak pengguna, dia perlu log masuk semula. Sudah tentu, ini bagus, kerana jika pengguna terlupa " Keluar", maka tiada perkara buruk akan berlaku. Penyerang tidak akan dapat menggunakan akaun pengguna. Lebih-lebih lagi, jika penggunaan kuki ia boleh dicuri, digantikan dalam penyemak imbas anda, dan akibatnya penyerang diberi kuasa menggunakan data orang lain, tanpa mengetahui kata laluan. Tetapi tidak mungkin untuk mencuri sesi, kerana semua parameter disimpan pada pelayan, dan tidak ada cara untuk mengetahui tentangnya.

Oleh itu, cuba dalam amalan anda terutamanya menggunakan sesi, tidak bersih biskut.

Dan akhirnya, saya ingin memberi amaran kepada anda tentang kesilapan yang sangat biasa. Jangan sekali-kali mengeluarkan data ke penyemak imbas sebelum ini menggunakan fungsi session_start()., jika tidak ia akan membuang ralat. Iaitu, anda tidak boleh menulis seperti ini:

echo "Hello";
session_start();
?>

Ralat akan berlaku semasa menjalankan skrip ini. Peraturan yang sama digunakan dengan biskut (fungsi setcookie().). Jadi, saya rasa semuanya jelas di sini.

Untuk sesi dalam PHP, maka, sudah tentu, ia boleh digunakan untuk menyimpan statistik, pengesahan, tetapan pengguna peribadi dan perkara lain yang serupa.

Salam, masyarakat yang dikasihi.

Pertama sekali, saya ingin mengucapkan terima kasih atas sumber yang sangat berguna. Lebih daripada sekali saya telah menemui banyak idea menarik dan nasihat praktikal di sini.

Tujuan artikel ini adalah untuk menyerlahkan perangkap menggunakan sesi dalam PHP. Sudah tentu, terdapat dokumentasi PHP dan banyak contoh, dan artikel ini tidak bertujuan untuk menjadi panduan lengkap. Ia direka untuk mendedahkan beberapa nuansa bekerja dengan sesi dan melindungi pembangun daripada pembaziran masa yang tidak perlu.

Contoh penggunaan sesi yang paling biasa ialah, sudah tentu, kebenaran pengguna. Mari kita mulakan dengan pelaksanaan yang paling asas untuk membangunkannya secara beransur-ansur apabila tugas baru timbul.

(Untuk menjimatkan ruang dan masa, kami akan mengehadkan contoh kami kepada hanya fungsi sesi itu sendiri, dan bukannya membina di sini aplikasi ujian lengkap dengan hierarki kelas yang cantik, pengendalian ralat yang komprehensif dan perkara bagus yang lain).

Fungsi startSession() ( // Jika sesi telah dimulakan, berhenti melaksanakan dan kembalikan TRUE // (parameter session.auto_start dalam fail tetapan php.ini mesti dilumpuhkan - nilai lalai) jika (session_id()) kembali true; else return session_start(); // Nota: Sebelum versi 5.3.0, fungsi session_start() mengembalikan TRUE walaupun ralat berlaku. // Jika anda menggunakan versi sebelum 5.3.0, lakukan semakan tambahan untuk session_id() // selepas memanggil session_start() ) function destroySession() ( if (session_id()) ( // Jika terdapat sesi aktif, padamkan kuki sesi, setcookie(session_name(), session_id(), time( )-60*60*24); // dan musnahkan session session_unset( ); session_destroy(); ) )

Catatan: Diandaikan bahawa pembaca mempunyai pengetahuan asas tentang sesi PHP, jadi kami tidak akan merangkumi prinsip operasi fungsi session_start() dan session_destroy() di sini. Tugas susun atur borang log masuk dan pengesahan pengguna tidak berkaitan dengan topik artikel, jadi kami juga akan meninggalkannya. Izinkan saya hanya mengingatkan anda bahawa untuk mengenal pasti pengguna dalam setiap permintaan berikutnya, pada saat log masuk berjaya, kami perlu menyimpan pengecam pengguna dalam pembolehubah sesi (bernama userid, contohnya), yang akan tersedia dalam semua permintaan berikutnya dalam hayat sesi. Ia juga perlu untuk melaksanakan pemprosesan hasil fungsi startSession() kami. Jika fungsi mengembalikan FALSE, paparkan borang log masuk dalam penyemak imbas. Jika fungsi mengembalikan TRUE, dan pembolehubah sesi yang mengandungi pengecam pengguna yang dibenarkan (dalam kes kami - id pengguna), wujud - paparkan halaman pengguna yang dibenarkan (untuk mendapatkan maklumat lanjut tentang pengendalian ralat, lihat tambahan bertarikh 2013-06- 07 dalam bahagian pembolehubah sesi).

Setakat ini semuanya jelas. Soalan bermula apabila anda perlu melaksanakan kawalan ketidakaktifan pengguna (masa tamat masa), membolehkan berbilang pengguna berfungsi serentak dalam satu penyemak imbas dan juga melindungi sesi daripada penggunaan tanpa kebenaran. Ini akan dibincangkan di bawah.

Memantau ketidakaktifan pengguna menggunakan alat PHP terbina dalam

Soalan pertama yang sering timbul dalam kalangan pembangun semua jenis konsol untuk pengguna ialah penamatan automatik sesi sekiranya pengguna tidak aktif. Tidak ada yang lebih mudah daripada melakukan ini menggunakan keupayaan terbina dalam PHP. (Pilihan ini tidak boleh dipercayai atau fleksibel, tetapi kami akan mempertimbangkannya untuk kesempurnaan).

Fungsi startSession() ( // Tamat masa tidak aktif pengguna (dalam saat) $sessionLifetime = 300; if (session_id()) return true; // Tetapkan kuki seumur hidup ini_set("session.cookie_lifetime", $sessionLifetime); // Jika pengguna tamat masa tidak aktif ditetapkan, tetapkan jangka hayat sesi pada pelayan // Nota: Untuk pelayan pengeluaran, disyorkan untuk pratetap parameter ini dalam fail php.ini jika ($sessionLifetime) ini_set("session.gc_maxlifetime", $sessionLifetime) ; jika (session_start( )) ( setcookie(session_name(), session_id(), time()+$sessionLifetime); return true; ) else return false; )

Sedikit penjelasan. Seperti yang anda ketahui, PHP menentukan sesi mana yang perlu dilancarkan oleh nama kuki yang dihantar oleh penyemak imbas dalam pengepala permintaan. Penyemak imbas pula menerima kuki ini daripada pelayan, di mana fungsi session_start() meletakkannya. Jika kuki penyemak imbas telah tamat tempoh, ia tidak akan dihantar dalam permintaan, yang bermaksud PHP tidak akan dapat menentukan sesi mana yang hendak dimulakan dan akan menganggap ini sebagai mencipta sesi baharu. Parameter tetapan PHP session.gc_maxlifetime, yang ditetapkan sama dengan tamat masa ketidakaktifan pengguna kami, menetapkan jangka hayat sesi PHP dan dikawal oleh pelayan. Mengawal seumur hidup sesi berfungsi seperti berikut (di sini kami menganggap contoh menyimpan sesi dalam fail sementara sebagai pilihan yang paling biasa dan lalai dalam PHP).

Apabila sesi baharu dibuat, fail dipanggil sess_ dicipta dalam set direktori sebagai direktori storan sesi dalam parameter tetapan PHP session.save_path , Di mana - pengecam sesi. Seterusnya, dalam setiap permintaan, pada masa melancarkan sesi yang sedia ada, PHP mengemas kini masa pengubahsuaian fail ini. Oleh itu, dalam setiap permintaan berikutnya, PHP, dengan perbezaan antara masa semasa dan masa pengubahsuaian terakhir fail sesi, boleh menentukan sama ada sesi itu aktif atau hayatnya telah pun tamat tempoh. (Mekanisme untuk memadam fail sesi lama dibincangkan dengan lebih terperinci dalam bahagian seterusnya.)

Catatan: Perlu diingatkan di sini bahawa parameter session.gc_maxlifetime digunakan untuk semua sesi dalam satu pelayan (lebih tepat lagi, dalam satu proses PHP utama). Dalam praktiknya, ini bermakna jika beberapa tapak dijalankan pada pelayan, dan setiap daripadanya mempunyai tamat masa ketidakaktifan pengguna sendiri, maka menetapkan parameter ini pada salah satu tapak akan membawa kepada tetapannya untuk tapak lain. Perkara yang sama berlaku untuk pengehosan kongsi. Untuk mengelakkan situasi ini, direktori sesi berasingan digunakan untuk setiap tapak dalam pelayan yang sama. Menetapkan laluan ke direktori sesi dilakukan menggunakan parameter session.save_path dalam fail tetapan php.ini, atau dengan memanggil fungsi ini_set(). Selepas ini, sesi setiap tapak akan disimpan dalam direktori berasingan dan parameter session.gc_maxlifetime yang ditetapkan pada salah satu tapak hanya akan sah untuk sesinya. Kami tidak akan mempertimbangkan kes ini secara terperinci, terutamanya kerana kami mempunyai pilihan yang lebih fleksibel untuk memantau ketidakaktifan pengguna.

Mengawal ketidakaktifan pengguna menggunakan pembolehubah sesi

Nampaknya pilihan sebelumnya, untuk semua kesederhanaannya (hanya beberapa baris kod tambahan), memberikan semua yang kami perlukan. Tetapi bagaimana jika tidak setiap permintaan boleh dianggap sebagai hasil daripada aktiviti pengguna? Sebagai contoh, halaman mempunyai pemasa yang secara berkala membuat permintaan AJAX untuk menerima kemas kini daripada pelayan. Permintaan sedemikian tidak boleh dianggap sebagai aktiviti pengguna, yang bermaksud memanjangkan hayat sesi secara automatik adalah tidak betul dalam kes ini. Tetapi kami tahu bahawa PHP mengemas kini masa pengubahsuaian fail sesi secara automatik setiap kali fungsi session_start() dipanggil, yang bermaksud bahawa sebarang permintaan akan membawa kepada lanjutan hayat sesi dan tamat masa ketidakaktifan pengguna tidak akan berlaku. Selain itu, nota terakhir dari bahagian sebelumnya tentang selok-belok parameter session.gc_maxlifetime mungkin kelihatan terlalu mengelirukan dan sukar untuk dilaksanakan bagi sesetengah orang.

Untuk menyelesaikan masalah ini, kami akan meninggalkan penggunaan mekanisme PHP terbina dalam dan memperkenalkan beberapa pembolehubah sesi baharu yang akan membolehkan kami mengawal masa ketidakaktifan pengguna sendiri.

Function startSession($isUserActivity=true) ($sessionLifetime = 300; if (session_id()) return true; // Tetapkan jangka hayat kuki sebelum menutup penyemak imbas (kami akan mengawal segala-galanya di bahagian pelayan) ini_set("session. cookie_lifetime", 0); if (! session_start()) return false; $t = time(); if ($sessionLifetime) ( // Jika tamat masa ketidakaktifan pengguna ditetapkan, // semak masa berlalu sejak aktiviti pengguna terakhir // (masa permintaan terakhir apabila pembolehubah sesi lastactivity dikemas kini) jika (isset($_SESSION["lastactivity"]) && $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( // Jika masa berlalu sejak aktiviti terakhir pengguna, // adalah lebih besar daripada tamat masa tidak aktif, yang bermaksud sesi telah tamat tempoh dan anda perlu menamatkan sesi destroySession(); return false; ) else ( // Jika tamat masa belum berlaku, // dan jika permintaan itu datang hasil daripada aktiviti pengguna, // kemas kini pembolehubah lastactivity dengan nilai masa semasa, // dengan itu memanjangkan masa sesi dengan detik seumur hidup sesi lain jika ($isUserActivity) $_SESSION["lastactivity"] = $t; ) ) kembalikan benar; )

Mari kita ringkaskan. Dalam setiap permintaan, kami menyemak sama ada tamat masa telah dicapai sejak aktiviti pengguna terakhir sehingga saat semasa, dan jika ia telah dicapai, kami memusnahkan sesi dan mengganggu pelaksanaan fungsi, mengembalikan FALSE. Jika tamat masa belum dicapai, dan parameter $isUserActivity dengan nilai TRUE dihantar ke fungsi, kami mengemas kini masa aktiviti terakhir pengguna. Apa yang perlu kita lakukan ialah menentukan dalam skrip panggilan sama ada permintaan itu adalah hasil daripada aktiviti pengguna, dan jika tidak, panggil fungsi startSession dengan parameter $isUserActivity ditetapkan kepada FALSE.

Kemas kini dari 2013-06-07
Memproses hasil fungsi sessionStart().

Komen menunjukkan bahawa mengembalikan FALSE tidak memberikan pemahaman yang lengkap tentang punca ralat, dan ini benar-benar adil. Saya tidak menerbitkan pengendalian ralat terperinci di sini (panjang artikel sudah agak besar), kerana ini tidak berkaitan secara langsung dengan topik artikel. Tetapi memandangkan komen, saya akan menjelaskan.

Seperti yang anda lihat, fungsi sessionStart boleh mengembalikan FALSE dalam dua kes. Sama ada sesi tidak dapat dimulakan kerana beberapa ralat pelayan dalaman (contohnya, tetapan sesi yang salah dalam php.ini), atau seumur hidup sesi telah tamat tempoh. Dalam kes pertama, kami mesti mengubah hala pengguna ke halaman dengan ralat yang menyatakan bahawa terdapat masalah pada pelayan dan borang untuk menghubungi sokongan. Dalam kes kedua, kami mesti memindahkan pengguna ke borang log masuk dan memaparkan mesej yang sepadan di dalamnya yang menyatakan bahawa sesi telah tamat tempoh. Untuk melakukan ini, kita perlu memasukkan kod ralat dan mengembalikan kod yang sepadan dan bukannya FALSE, dan dalam kaedah panggilan, semak dan bertindak sewajarnya.

Sekarang, walaupun sesi pada pelayan masih wujud, ia akan dimusnahkan pada kali pertama ia diakses jika tamat masa tidak aktif pengguna telah tamat tempoh. Dan ini akan berlaku tanpa mengira jangka hayat sesi yang ditetapkan dalam tetapan PHP global.

Catatan: Apakah yang berlaku jika penyemak imbas ditutup dan kuki nama sesi dimusnahkan secara automatik? Permintaan kepada pelayan pada kali berikutnya penyemak imbas dibuka tidak akan mengandungi kuki sesi, dan pelayan tidak akan dapat membuka sesi dan menyemak tamat masa tidak aktif pengguna. Bagi kami, ini sama dengan mencipta sesi baharu dan tidak menjejaskan fungsi atau keselamatan dalam apa jua cara. Tetapi persoalan yang wajar timbul - siapa yang akan memusnahkan sesi lama, jika sehingga kini kita telah memusnahkannya selepas tamat masa tamat? Atau adakah ia kini akan digantung dalam direktori sesi selama-lamanya? Untuk membersihkan sesi lama dalam PHP, terdapat mekanisme yang dipanggil pengumpulan sampah. Ia berjalan pada masa permintaan seterusnya kepada pelayan dan mengosongkan semua sesi lama berdasarkan tarikh pengubahsuaian terakhir fail sesi. Tetapi mekanisme pengumpulan sampah tidak bermula dengan setiap permintaan kepada pelayan. Kekerapan (atau lebih tepatnya, kebarangkalian) pelancaran ditentukan oleh dua parameter tetapan session.gc_probability dan session.gc_divisor. Hasil pembahagian parameter pertama dengan yang kedua adalah kebarangkalian melancarkan mekanisme kutipan sampah. Oleh itu, agar mekanisme penjelasan sesi dilancarkan dengan setiap permintaan kepada pelayan, parameter ini mesti ditetapkan kepada nilai yang sama, contohnya "1". Pendekatan ini menjamin direktori sesi yang bersih, tetapi jelas terlalu mahal untuk pelayan. Oleh itu, pada sistem pengeluaran, nilai lalai session.gc_divisor ditetapkan kepada 1000, yang bermaksud mekanisme kutipan sampah akan berjalan dengan kebarangkalian 1/1000. Jika anda mencuba tetapan ini dalam fail php.ini anda, anda mungkin dapati bahawa dalam kes yang diterangkan di atas, apabila penyemak imbas menutup dan mengosongkan semua kukinya, masih terdapat sesi lama dalam direktori sesi untuk seketika. Tetapi ini tidak perlu membimbangkan anda, kerana... seperti yang telah dinyatakan, ini tidak sama sekali menjejaskan keselamatan mekanisme kami.

Kemas kini dari 2013-06-07

Menghalang skrip daripada membeku kerana penguncian fail sesi

Komen tersebut membangkitkan isu pembekuan skrip yang dijalankan secara serentak kerana fail sesi disekat (pilihan yang paling menarik ialah tinjauan panjang).

Sebagai permulaan, saya perhatikan bahawa masalah ini tidak secara langsung bergantung pada beban pelayan atau bilangan pengguna. Sudah tentu, lebih banyak permintaan, lebih perlahan skrip dilaksanakan. Tetapi ini adalah pergantungan tidak langsung. Masalah muncul hanya dalam satu sesi, apabila pelayan menerima beberapa permintaan bagi pihak seorang pengguna (contohnya, salah satunya ialah tinjauan panjang dan selebihnya adalah permintaan biasa). Setiap permintaan cuba mengakses fail sesi yang sama, dan jika permintaan sebelumnya tidak membuka kunci fail, maka permintaan yang berikutnya akan menunggu.

Untuk memastikan fail sesi terkunci pada tahap minimum, adalah amat disyorkan untuk menutup sesi dengan memanggil fungsi session_write_close() serta-merta selepas semua tindakan dengan pembolehubah sesi telah selesai. Dalam amalan, ini bermakna anda tidak sepatutnya menyimpan segala-galanya dalam pembolehubah sesi dan mengaksesnya sepanjang pelaksanaan skrip. Dan jika anda perlu menyimpan beberapa data yang berfungsi dalam pembolehubah sesi, kemudian bacanya dengan segera apabila sesi bermula, simpannya dalam pembolehubah tempatan untuk kegunaan kemudian dan tutup sesi (bermaksud menutup sesi menggunakan fungsi session_write_close, dan tidak memusnahkannya menggunakan session_destroy ).

Dalam contoh kami, ini bermakna sejurus selepas membuka sesi, menyemak hayatnya dan kewujudan pengguna yang dibenarkan, kami mesti membaca dan menyimpan semua pembolehubah sesi tambahan yang diperlukan oleh aplikasi (jika ada), kemudian tutup sesi menggunakan panggilan ke session_write_close() dan meneruskan pelaksanaan skrip, sama ada tinjauan panjang atau permintaan biasa.

Melindungi sesi daripada penggunaan yang tidak dibenarkan

Cuba kita bayangkan keadaannya. Salah seorang pengguna anda mendapat Trojan yang merompak kuki penyemak imbas (di mana sesi kami disimpan) dan menghantarnya ke e-mel yang ditentukan. Penyerang memperoleh kuki dan menggunakannya untuk menipu permintaan bagi pihak pengguna kami yang dibenarkan. Pelayan berjaya menerima dan memproses permintaan ini seolah-olah ia datang daripada pengguna yang dibenarkan. Jika pengesahan tambahan alamat IP tidak dilaksanakan, serangan sedemikian akan membawa kepada kejayaan penggodaman akaun pengguna dengan semua akibat yang berikutnya.

Mengapa ini boleh berlaku? Jelas sekali, kerana nama dan pengecam sesi sentiasa sama untuk sepanjang hayat sesi, dan jika anda menerima data ini, anda boleh menghantar permintaan dengan mudah bagi pihak pengguna lain (sudah tentu, sepanjang hayat sesi ini). Ini mungkin bukan jenis serangan yang paling biasa, tetapi secara teorinya ia kelihatan agak boleh dilaksanakan, terutamanya memandangkan Trojan sedemikian tidak memerlukan hak pentadbir untuk merompak kuki penyemak imbas pengguna.

Bagaimanakah anda boleh melindungi diri anda daripada serangan seperti ini? Sekali lagi, jelas sekali, dengan mengehadkan hayat pengecam sesi dan menukar pengecam secara berkala dalam sesi yang sama. Kami juga boleh menukar nama sesi dengan memadam sepenuhnya yang lama dan mencipta sesi baharu, menyalin semua pembolehubah sesi daripada yang lama ke dalamnya. Tetapi ini tidak menjejaskan intipati pendekatan, jadi untuk kesederhanaan kami akan mengehadkan diri kami kepada hanya pengecam sesi.

Jelas sekali bahawa semakin pendek jangka hayat ID sesi, semakin sedikit masa penyerang perlu mendapatkan dan menggunakan kuki untuk memalsukan permintaan pengguna. Sebaik-baiknya, pengecam baharu harus digunakan untuk setiap permintaan, yang akan meminimumkan kemungkinan menggunakan sesi orang lain. Tetapi kami akan mempertimbangkan kes umum apabila masa penjanaan semula pengecam sesi ditetapkan sewenang-wenangnya.

(Kami akan meninggalkan bahagian kod yang telah dibincangkan).

Function startSession($isUserActivity=true) ( ​​​​ // Session identifier lifetime $idLifetime = 60; ... if ($idLifetime) ( // Jika seumur hidup pengecam sesi ditetapkan, // semak masa berlalu sejak sesi itu dicipta atau penjanaan semula terakhir // (masa permintaan terakhir apabila masa mula pembolehubah sesi dikemas kini) jika (isset($_SESSION["masa mula"])) ( jika ($t-$_SESSION["masa mula"] >= $ idLifetime) ( // Masa hayat pengecam sesi telah tamat // Jana pengecam baharu session_regenerate_id(true); $_SESSION["starttime"] = $t; ) ) else ( // Kita sampai di sini jika sesi baru sahaja telah dicipta // Tetapkan masa untuk menjana pengecam sesi kepada masa semasa $_SESSION["starttime"] = $t; ) ) return true; )

Jadi, apabila mencipta sesi baharu (yang berlaku apabila pengguna berjaya log masuk), kami menetapkan masa mula pembolehubah sesi, yang menyimpan untuk kami masa generasi terakhir pengecam sesi, kepada nilai yang sama dengan masa pelayan semasa. Seterusnya, dalam setiap permintaan, kami menyemak sama ada masa yang mencukupi (idLifetime) telah berlalu sejak generasi terakhir pengecam, dan jika ya, kami menjana yang baharu. Oleh itu, jika dalam tempoh hayat pengecam yang ditetapkan, penyerang yang menerima kuki pengguna yang dibenarkan tidak mempunyai masa untuk menggunakannya, permintaan palsu akan dianggap oleh pelayan sebagai tidak dibenarkan, dan penyerang akan dibawa ke halaman log masuk .

Catatan: ID sesi baharu masuk ke dalam kuki penyemak imbas apabila fungsi session_regenerate_id() dipanggil, yang menghantar kuki baharu, serupa dengan fungsi session_start(), jadi kami tidak perlu mengemas kini kuki itu sendiri.

Jika kami ingin menjadikan sesi kami seaman mungkin, sudah cukup untuk menetapkan jangka hayat pengecam kepada satu atau malah mengalih keluar fungsi session_regenerate_id() daripada kurungan dan mengalih keluar semua semakan, yang akan membawa kepada penjanaan semula pengecam dalam setiap permintaan. (Saya belum menguji kesan pendekatan ini pada prestasi, dan saya hanya boleh mengatakan bahawa fungsi session_regenerate_id(true) pada asasnya hanya melaksanakan 4 tindakan: menjana pengecam baharu, mencipta pengepala dengan kuki sesi, memadam yang lama dan mencipta fail sesi baharu).

Penyimpangan lirik: Jika Trojan ternyata sangat pintar sehingga ia tidak akan menghantar kuki kepada penyerang, tetapi mengatur penghantaran permintaan palsu yang telah disediakan dengan segera selepas menerima kuki, kaedah yang diterangkan di atas kemungkinan besar tidak akan dapat melindungi daripada itu. serangan, kerana antara masa Trojan menerima kuki dan penghantaran permintaan palsu hampir tidak ada perbezaan, dan terdapat kebarangkalian tinggi bahawa pada masa ini pengecam sesi tidak akan dijana semula.

Kemungkinan kerja serentak dalam satu pelayar bagi pihak beberapa pengguna

Tugas terakhir yang saya ingin pertimbangkan ialah keupayaan beberapa pengguna untuk bekerja serentak dalam satu pelayar. Ciri ini amat berguna pada peringkat ujian, apabila anda perlu mencontohi kerja serentak pengguna, dan adalah dinasihatkan untuk melakukan ini dalam penyemak imbas kegemaran anda, daripada menggunakan keseluruhan senjata yang tersedia atau membuka beberapa contoh penyemak imbas dalam mod inkognito .

Dalam contoh terdahulu kami, kami tidak menyatakan nama sesi secara eksplisit, jadi nama PHP lalai (PHPSESSID) telah digunakan. Ini bermakna semua sesi yang kami buat setakat ini telah menghantar kuki ke penyemak imbas di bawah nama PHPSESSID. Jelas sekali, jika nama kuki sentiasa sama, maka tidak ada cara untuk mengatur dua sesi dengan nama yang sama dalam penyemak imbas yang sama. Tetapi jika kami menggunakan nama sesi kami sendiri untuk setiap pengguna, masalah itu akan diselesaikan. Jom buat.

Function startSession($isUserActivity=true, $prefix=null) ( ... if (session_id()) return true; // Jika awalan pengguna diluluskan dalam parameter, // tetapkan nama sesi unik yang merangkumi ini awalan, // sebaliknya tetapkan nama biasa untuk semua pengguna (contohnya, MYPROJECT) session_name("MYPROJECT".($prefix ? "_".$prefix: ""));ini_set("session.cookie_lifetime", 0); jika (! session_start()) return false; ... )

Kini yang tinggal hanyalah untuk memastikan bahawa skrip panggilan melepasi awalan unik untuk setiap pengguna ke fungsi startSession(). Ini boleh dilakukan, sebagai contoh, dengan menghantar awalan dalam parameter GET/POST bagi setiap permintaan atau melalui kuki tambahan.

Kesimpulan

Kesimpulannya, saya akan menyediakan kod akhir lengkap fungsi kami untuk bekerja dengan sesi PHP, termasuk semua tugas yang dibincangkan di atas.

Fungsi startSession($isUserActivity=true, $prefix=null) ( $sessionLifetime = 300; $idLifetime = 60; if (session_id()) return true; session_name("MYPROJECT".($prefix ? "_".$prefix: "")); ini_set("session.cookie_lifetime", 0); if (! session_start()) return false; $t = time(); if ($sessionLifetime) ( if (isset($_SESSION["lastactivity"] ) && $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( destroySession(); return false; ) else ( if ($isUserActivity) $_SESSION["lastactivity"] = $t; ) ) if ($idLifetime ) ( if (isset($_SESSION["starttime"])) ( if ($t-$_SESSION["starttime"] >= $idLifetime) ( session_regenerate_id(true); $_SESSION["starttime"] = $t; ) ) else ( $_SESSION["starttime"] = $t; ) ) return true; ) function destroySession() ( if (session_id()) ( session_unset(); setcookie(session_name(), session_id(), time() -60*60*24); session_destroy(); ) )

Saya harap artikel ini dapat menjimatkan sedikit masa bagi mereka yang tidak pernah mendalami mekanisme sesi, dan memberikan gambaran yang cukup tentang mekanisme ini untuk mereka yang baru mula berjinak-jinak dengan PHP.