PHP da sessiya identifikatori himoyasi. PHP da seanslardan foydalanishning tuzoqlari PHP sessiyasi yordamida qiymat yoki massivdan o'tish

Assalomu alaykum, aziz jamoa.

Avvalo, sizga juda foydali manba uchun rahmat aytmoqchiman. Bu erda men bir necha bor ko'plab qiziqarli g'oyalar va amaliy maslahatlarni topdim.

Ushbu maqolaning maqsadi PHP da seanslardan foydalanishning kamchiliklarini ta'kidlashdir. Albatta, PHP hujjatlari va ko'plab misollar mavjud va bu maqola to'liq qo'llanma bo'lish uchun mo'ljallanmagan. U seanslar bilan ishlashning ba'zi nuanslarini ochib berish va ishlab chiquvchilarni keraksiz vaqtni yo'qotishdan himoya qilish uchun mo'ljallangan.

Seanslardan foydalanishning eng keng tarqalgan namunasi, albatta, foydalanuvchi avtorizatsiyasidir. Yangi vazifalar paydo bo'lishi bilan uni bosqichma-bosqich rivojlantirish uchun eng asosiy amalga oshirishdan boshlaylik.

(Makon va vaqtni tejash uchun biz bu erda chiroyli sinf ierarxiyasi, xatolarni to'liq hal qilish va boshqa yaxshi narsalarga ega bo'lgan to'liq huquqli test ilovasini yaratish o'rniga, misollarimizni faqat sessiya funktsiyalari bilan cheklaymiz).

startSession() funksiyasi ( // Agar seans allaqachon boshlangan bo'lsa, bajarishni to'xtating va TRUE qaytaring // (php.ini sozlamalari faylidagi session.auto_start parametri o'chirilgan bo'lishi kerak - standart qiymat) agar (session_id()) qaytsa true; else return session_start(); // Eslatma: 5.3.0 versiyasidan oldin, session_start() funksiyasi xatolik yuz bergan bo‘lsa ham TRUE qiymatini qaytardi. // Agar siz 5.3.0 dan oldingi versiyadan foydalanayotgan bo‘lsangiz, qo‘shimcha tekshiruvni bajaring. session_id() uchun // session_start() ) funksiyasini chaqirgandan so'ng destroySession() ( if (session_id()) ( // Agar faol seans bo'lsa, seans cookie-fayllarini, setcookie(session_name(), session_id(), time( )-60*60*24); // va sessiyani yo'q qilish session_unset( ); session_destroy(); ) )

Eslatma: O'quvchi PHP seanslari bo'yicha boshlang'ich bilimga ega deb taxmin qilinadi, shuning uchun biz bu erda session_start() va session_destroy() funksiyalarining ishlash tamoyilini ko'rib chiqmaymiz. Kirish formasini joylashtirish va foydalanuvchi autentifikatsiyasi vazifalari maqola mavzusi bilan bog'liq emas, shuning uchun biz ularni ham o'tkazib yuboramiz. Sizga shuni eslatib o'tamanki, har bir keyingi so'rovda foydalanuvchini aniqlash uchun, muvaffaqiyatli tizimga kirish vaqtida biz foydalanuvchi identifikatorini barcha keyingi so'rovlarda mavjud bo'lgan sessiya o'zgaruvchisida (masalan, foydalanuvchi nomi bilan) saqlashimiz kerak. sessiya hayoti. Shuningdek, startSession() funksiyamiz natijasini qayta ishlashni amalga oshirish kerak. Agar funktsiya FALSE qiymatini qaytarsa, brauzerda kirish formasini ko'rsating. Agar funktsiya TRUE qiymatini qaytarsa ​​va vakolatli foydalanuvchi identifikatorini o'z ichiga olgan seans o'zgaruvchisi mavjud bo'lsa (bizning holatda - foydalanuvchi identifikatori) - vakolatli foydalanuvchi sahifasini ko'rsating (xatolarni hal qilish haqida qo'shimcha ma'lumot olish uchun 2013-06-yildagi qo'shimchaga qarang). 07 sessiya o'zgaruvchilari bo'limida).

Hozircha hamma narsa aniq. Savollar foydalanuvchi harakatsizligini nazorat qilish (sessiya vaqti tugashi), bir vaqtning o'zida bir brauzerda bir nechta foydalanuvchilarning ishlashini ta'minlash, shuningdek, seanslarni ruxsatsiz foydalanishdan himoya qilish kerak bo'lganda boshlanadi. Bu quyida muhokama qilinadi.

O'rnatilgan PHP vositalaridan foydalangan holda foydalanuvchi harakatsizligini nazorat qilish Foydalanuvchilar uchun turli xil konsollarni ishlab chiquvchilar orasida tez-tez paydo bo'ladigan birinchi savol, foydalanuvchi tomonidan harakatsizlik bo'lsa, sessiyani avtomatik ravishda tugatishdir. PHP ning o'rnatilgan imkoniyatlaridan foydalangan holda buni amalga oshirishdan osonroq narsa yo'q. (Ushbu variant ayniqsa ishonchli yoki moslashuvchan emas, lekin biz uni to'liqlik uchun ko'rib chiqamiz).

Funktsiya startSession() ( // Foydalanuvchining harakatsizligi vaqti (soniyalarda) $sessionLifetime = 300; agar (session_id()) rost qaytarilsa; // Cookie ishlash muddatini o'rnating ini_set("session.cookie_lifetime", $sessionLifetime); // Agar foydalanuvchi harakatsizlik vaqti o'rnatildi, serverda seansning ishlash muddatini belgilang // Eslatma: Ishlab chiqarish serveri uchun bu parametrlarni php.ini faylida oldindan o'rnatish tavsiya etiladi, agar ($sessionLifetime) ini_set("session.gc_maxlifetime", $sessionLifetime) ; if (session_start( )) ( setcookie(session_name(), session_id(), time()+$sessionLifetime); return true; ) aks holda false qaytaradi; )

Bir nechta tushuntirishlar. Ma'lumki, PHP qaysi seansni ishga tushirish kerakligini so'rov sarlavhasida brauzer tomonidan yuborilgan cookie nomi bilan aniqlaydi. Brauzer, o'z navbatida, ushbu cookie-faylni serverdan oladi, u erda session_start() funksiyasi uni joylashtiradi. Agar brauzer cookie-faylining muddati tugagan bo'lsa, u so'rovda yuborilmaydi, ya'ni PHP qaysi seansni boshlashni aniqlay olmaydi va buni yangi seans yaratish sifatida ko'radi. PHP sozlamalari session.gc_maxlifetime parametri, bu bizning foydalanuvchining harakatsizligi vaqti tugashiga teng, PHP seansining ishlash muddatini belgilaydi va server tomonidan boshqariladi. Seansning ishlash muddatini boshqarish quyidagicha ishlaydi (bu erda biz PHPda eng keng tarqalgan va standart variant sifatida vaqtinchalik fayllarda seanslarni saqlash misolini ko'rib chiqamiz).

Yangi seans yaratilganda, PHP sozlamalari session.save_path parametrida seanslarni saqlash uchun katalog sifatida o'rnatilgan katalogda sess_ nomli fayl yaratiladi, bu erda sessiya identifikatori. Keyinchalik, har bir so'rovda, mavjud sessiyani ishga tushirish vaqtida PHP ushbu faylni o'zgartirish vaqtini yangilaydi. Shunday qilib, har bir keyingi so'rovda PHP joriy vaqt va sessiya faylini oxirgi o'zgartirish vaqti o'rtasidagi farqga ko'ra, sessiya faol yoki uning muddati allaqachon tugaganligini aniqlashi mumkin. (Eski seans fayllarini o'chirish mexanizmi keyingi bo'limda batafsilroq muhokama qilinadi.)

Eslatma: Bu yerda shuni ta'kidlash kerakki, session.gc_maxlifetime parametri bitta server ichidagi barcha seanslar uchun amal qiladi (aniqrog'i, bitta asosiy PHP jarayoni doirasida). Amalda, bu shuni anglatadiki, agar serverda bir nechta saytlar ishlayotgan bo'lsa va ularning har biri o'z foydalanuvchi harakatsizligi uchun vaqt tugashiga ega bo'lsa, u holda saytlardan birida ushbu parametrni o'rnatish uni boshqa saytlar uchun sozlashga olib keladi. Xuddi shu narsa umumiy hosting uchun ham amal qiladi. Bunday vaziyatni oldini olish uchun bitta server ichidagi har bir sayt uchun alohida seans kataloglari qo'llaniladi. Seanslar katalogiga yo'lni o'rnatish php.ini sozlamalari faylidagi session.save_path parametri yoki ini_set() funksiyasini chaqirish orqali amalga oshiriladi. Shundan so'ng, har bir saytning sessiyalari alohida kataloglarda saqlanadi va saytlardan birida o'rnatilgan session.gc_maxlifetime parametri faqat uning sessiyasi uchun amal qiladi. Biz bu ishni batafsil ko'rib chiqmaymiz, ayniqsa, bizda foydalanuvchi harakatsizligini kuzatish uchun yanada moslashuvchan variant mavjud.

Seans o'zgaruvchilari yordamida foydalanuvchi harakatsizligini nazorat qilish Aftidan, avvalgi variant o'zining soddaligi uchun (faqat bir nechta qo'shimcha kod qatorlari) bizga kerak bo'lgan hamma narsani beradi. Ammo har bir so'rovni foydalanuvchi faoliyati natijasi sifatida ko'rib chiqish mumkin bo'lmasa-chi? Misol uchun, sahifada vaqti-vaqti bilan serverdan yangilanishlarni olish uchun AJAX so'rovini yuboradigan taymer mavjud. Bunday so'rovni foydalanuvchi faoliyati sifatida ko'rib bo'lmaydi, ya'ni bu holda seans muddatini avtomatik ravishda uzaytirish to'g'ri emas. Lekin biz bilamizki, PHP har safar session_start() funksiyasi chaqirilganda seans faylining o‘zgartirish vaqtini avtomatik ravishda yangilaydi, ya’ni har qanday so‘rov seansning ishlash muddatini uzaytiradi va foydalanuvchi harakatsizligi vaqti hech qachon sodir bo‘lmaydi. Bundan tashqari, sessiya.gc_maxlifetime parametrining nozik jihatlari haqidagi oldingi qismdagi oxirgi eslatma ba'zilar uchun juda chalkash va amalga oshirish qiyin bo'lib tuyulishi mumkin.

Ushbu muammoni hal qilish uchun biz o'rnatilgan PHP mexanizmlaridan voz kechamiz va foydalanuvchining harakatsizligi vaqtini o'zimiz nazorat qilishimizga imkon beradigan bir nechta yangi seans o'zgaruvchilarini kiritamiz.

Funktsiya startSession($isUserActivity=true) ($sessionLifetime = 300; agar (session_id()) rost qaytarilsa; // Brauzerni yopishdan oldin cookie-faylning ishlash muddatini belgilang (biz hamma narsani server tomonida nazorat qilamiz) ini_set("session. cookie_lifetime", 0) ; if (! session_start()) return false; $t = time(); if ($sessionLifetime) ( // Agar foydalanuvchi harakatsizligi vaqti oʻrnatilgan boʻlsa, // foydalanuvchining oxirgi harakatidan beri oʻtgan vaqtni tekshiring. // (so'nggi faollik seansi o'zgaruvchisi yangilangan oxirgi so'rov vaqti) if (isset($_SESSION["so'nggi faollik"]) && $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( // Agar o'tgan vaqtdan beri o'tgan bo'lsa foydalanuvchining oxirgi faolligi, / / ​​harakatsizlik taym-autidan kattaroqdir, bu seansning muddati tugaganligini bildiradi va siz seansni tugatishingiz kerak destroySession(); return false; ) else ( // Agar kutish vaqti hali roʻy bermagan boʻlsa, // va agar so'rov foydalanuvchi faoliyati natijasida kelgan bo'lsa, // oxirgi faollik o'zgaruvchisini joriy bir martalik qiymati bilan yangilang, // shu bilan seans vaqtini boshqa bir seansLifetime soniyaga uzaytiring, agar ($isUserActivity) $_SESSION["lastactivity"] = $t; ) ) rostni qaytaradi; )

Keling, xulosa qilaylik. Har bir so'rovda biz oxirgi foydalanuvchi harakatidan hozirgi vaqtgacha vaqt tugashiga erishilganligini tekshiramiz va agar unga erishilgan bo'lsa, biz sessiyani yo'q qilamiz va funktsiyaning bajarilishini to'xtatib, FALSE qaytaramiz. Agar kutish vaqti tugamagan bo'lsa va funktsiyaga TRUE qiymatiga ega $isUserActivity parametri uzatilsa, biz foydalanuvchining oxirgi faoliyati vaqtini yangilaymiz. Biz qilishimiz kerak bo'lgan narsa qo'ng'iroq skriptida so'rov foydalanuvchi faoliyati natijasi ekanligini aniqlash va agar bo'lmasa, $isUserActivity parametri FALSE ga o'rnatilgan startSession funksiyasini chaqirish.

2013-06-07 dan qo‘shilgan. sessionStart() funksiyasi natijasini qayta ishlash

Sharhlarda ta'kidlanishicha, FALSE ni qaytarish xato sababini to'liq tushunishni ta'minlamaydi va bu mutlaqo adolatli. Men bu erda xatolarni batafsil ko'rib chiqishni nashr qilmadim (maqolaning uzunligi allaqachon juda katta), chunki bu maqola mavzusiga bevosita bog'liq emas. Ammo sharhlarni hisobga olgan holda, men aniqlik kiritaman.

Ko'rib turganingizdek, sessionStart funksiyasi ikkita holatda FALSE ni qaytarishi mumkin. Yoki baʼzi ichki server xatolari (masalan, php.iniʼdagi notoʻgʻri seans sozlamalari) tufayli seansni ishga tushirib boʻlmadi yoki sessiya muddati tugagan. Birinchi holda, biz foydalanuvchini serverda muammolar mavjudligini va qo'llab-quvvatlash bilan bog'lanish shaklini ko'rsatadigan xato bilan sahifaga yo'naltirishimiz kerak. Ikkinchi holda, biz foydalanuvchini login formasiga o'tkazishimiz va unda sessiya muddati tugaganligi to'g'risida tegishli xabarni ko'rsatishimiz kerak. Buning uchun biz xato kodlarini kiritishimiz va FALSE o'rniga mos keladigan kodni qaytarishimiz kerak va qo'ng'iroq qilish usulida uni tekshiring va shunga muvofiq harakat qiling.

Endi, agar serverdagi seans hali ham mavjud bo'lsa ham, agar foydalanuvchining harakatsizlik vaqti tugagan bo'lsa, u birinchi marta kirishda yo'q qilinadi. Va bu global PHP sozlamalarida qanday seans muddati o'rnatilganidan qat'iy nazar sodir bo'ladi.

Eslatma: Agar brauzer yopilsa va seans nomi cookie-fayllari avtomatik ravishda yo'q qilingan bo'lsa nima bo'ladi? Brauzer keyingi safar ochilganda serverga yuborilgan so‘rovda seans kukilari bo‘lmaydi va server sessiyani ochib, foydalanuvchining harakatsizligi vaqtini tekshira olmaydi. Biz uchun bu yangi seans yaratishga teng va hech qanday funksionallik yoki xavfsizlikka ta'sir qilmaydi. Ammo adolatli savol tug'iladi - agar biz hozirgacha taym-aut tugaganidan keyin uni yo'q qilgan bo'lsak, eski sessiyani kim yo'q qiladi? Yoki u endi sessiyalar katalogida abadiy qoladimi? PHP da eski seanslarni tozalash uchun axlat yig'ish mexanizmi mavjud. U serverga keyingi so'rov yuborilgan vaqtda ishlaydi va sessiya fayllarini oxirgi o'zgartirish sanasi asosida barcha eski seanslarni o'chiradi. Ammo axlat yig'ish mexanizmi serverga har bir so'rov bilan boshlanmaydi. Ishga tushirish chastotasi (aniqrog'i, ehtimollik) session.gc_probability va session.gc_divisor ikkita sozlamalar parametrlari bilan belgilanadi. Birinchi parametrni ikkinchisiga bo'lish natijasi - axlat yig'ish mexanizmini ishga tushirish ehtimoli. Shunday qilib, serverga har bir so'rov bilan sessiyani tozalash mexanizmi ishga tushishi uchun ushbu parametrlar teng qiymatlarga o'rnatilishi kerak, masalan, "1". Ushbu yondashuv toza seans katalogini kafolatlaydi, lekin server uchun juda qimmat ekanligi aniq. Shuning uchun ishlab chiqarish tizimlarida session.gc_divisor ning sukut bo'yicha qiymati 1000 ga o'rnatiladi, ya'ni axlat yig'ish mexanizmi 1/1000 ehtimollik bilan ishlaydi. Agar siz php.ini faylingizda ushbu sozlamalar bilan tajriba o'tkazsangiz, yuqorida tavsiflangan holatda, brauzer yopilganda va barcha cookie-fayllarni o'chirganda, seanslar katalogida bir muncha vaqtgacha eski seanslar qolayotganini sezishingiz mumkin. Ammo bu sizni tashvishga solmasligi kerak, chunki ... Yuqorida aytib o'tilganidek, bu bizning mexanizmimizning xavfsizligiga hech qanday ta'sir qilmaydi.

2013-06-07 dan yangilanish Seans fayli blokirovkasi tufayli skriptlarni muzlatishning oldini olish

Izohlarda seans fayli bloklanganligi sababli bir vaqtning o'zida ishlayotgan skriptlarni muzlatish masalasi ko'tarildi (eng ajoyib variant - uzoq so'rov).

Boshlash uchun shuni ta'kidlaymanki, bu muammo to'g'ridan-to'g'ri server yukiga yoki foydalanuvchilar soniga bog'liq emas. Albatta, so'rovlar qanchalik ko'p bo'lsa, skriptlar shunchalik sekin bajariladi. Ammo bu bilvosita bog'liqlik. Muammo faqat bitta seansda, server bir foydalanuvchi nomidan bir nechta so'rovlarni qabul qilganda paydo bo'ladi (masalan, ulardan biri uzoq so'rov, qolganlari oddiy so'rovlar). Har bir so'rov bir xil seans fayliga kirishga harakat qiladi va agar oldingi so'rov faylni qulfdan chiqarmagan bo'lsa, keyingi so'rov to'xtab qoladi.

Seans faylini blokirovka qilishni minimal darajada ushlab turish uchun sessiya o'zgaruvchilari bilan barcha amallar bajarilgandan so'ng darhol session_write_close() funksiyasini chaqirish orqali sessiyani yopish tavsiya etiladi. Amalda, bu seans o'zgaruvchilarida hamma narsani saqlamasligingiz va skriptning bajarilishi davomida ularga kirishingiz kerakligini anglatadi. Va agar siz ba'zi ishchi ma'lumotlarni sessiya o'zgaruvchilarida saqlashingiz kerak bo'lsa, ularni seans boshlanganda darhol o'qing, keyinroq foydalanish uchun ularni mahalliy o'zgaruvchilarga saqlang va sessiyani yoping (ya'ni sessiyani session_write_close funksiyasidan foydalanib yopish va sessiya_destroy yordamida yo'q qilmaslikni anglatadi) ).

Bizning misolimizda bu shuni anglatadiki, seans ochilgandan so'ng, uning ishlash muddati va vakolatli foydalanuvchi mavjudligi tekshirilgandan so'ng, biz ilova tomonidan talab qilinadigan barcha qo'shimcha seans o'zgaruvchilarini (agar mavjud bo'lsa) o'qishimiz va saqlashimiz kerak, so'ngra qo'ng'iroq yordamida sessiyani yopishimiz kerak. session_write_close() va skriptning bajarilishini davom ettiring, xoh uzoq so'rov bo'lsin, xoh oddiy so'rov.

Seanslarni ruxsatsiz foydalanishdan himoya qilish Keling, vaziyatni tasavvur qilaylik. Sizning foydalanuvchilaringizdan biri brauzer cookie-fayllarini o'g'irlaydigan (bizning sessiyamiz saqlanadigan) troyan oladi va uni belgilangan elektron pochta manziliga yuboradi. Buzg'unchi cookie-faylni oladi va undan bizning vakolatli foydalanuvchimiz nomidan so'rovni buzish uchun foydalanadi. Server ushbu so'rovni vakolatli foydalanuvchidan kelgandek muvaffaqiyatli qabul qiladi va qayta ishlaydi. Agar IP-manzilni qo'shimcha tekshirish amalga oshirilmasa, bunday hujum foydalanuvchining akkauntini muvaffaqiyatli buzishga olib keladi va barcha oqibatlarga olib keladi.

Nima uchun bu mumkin edi? Shubhasiz, chunki nom va sessiya identifikatori seansning butun muddati davomida har doim bir xil bo'ladi va agar siz ushbu ma'lumotni olsangiz, boshqa foydalanuvchi nomidan so'rovlarni osongina yuborishingiz mumkin (albatta, ushbu sessiya muddati davomida). Bu hujumning eng keng tarqalgan turi bo'lmasligi mumkin, ammo nazariy jihatdan bu juda mumkin ko'rinadi, ayniqsa bunday troyan foydalanuvchining brauzer cookie-fayllarini o'g'irlash uchun administrator huquqlariga ham muhtoj emasligini hisobga olsak.

O'zingizni bunday hujumlardan qanday himoya qilishingiz mumkin? Yana, shubhasiz, seans identifikatorining ishlash muddatini cheklash va identifikatorni vaqti-vaqti bilan bir seans ichida o'zgartirish orqali. Bundan tashqari, eskisini butunlay o'chirib, yangi seans yaratish, barcha seans o'zgaruvchilarini eskisidan nusxa ko'chirish orqali sessiya nomini o'zgartirishimiz mumkin. Ammo bu yondashuvning mohiyatiga ta'sir qilmaydi, shuning uchun soddaligi uchun biz faqat sessiya identifikatori bilan cheklanamiz.

Seans identifikatorining ishlash muddati qanchalik qisqa bo'lsa, tajovuzkor foydalanuvchi so'rovini soxtalashtirish uchun cookie-fayllarni olishi va undan foydalanishi uchun shunchalik kam vaqt ketishi aniq. Ideal holda, har bir so'rov uchun yangi identifikatordan foydalanish kerak, bu boshqa birovning sessiyasidan foydalanish imkoniyatini kamaytiradi. Ammo biz seans identifikatorini qayta tiklash vaqti o'zboshimchalik bilan o'rnatilganda umumiy holatni ko'rib chiqamiz.

(Biz kodning allaqachon muhokama qilingan qismini o'tkazib yuboramiz).

Funktsiya startSession($isUserActivity=true) ( ​​// Seans identifikatorining ishlash muddati $idLifetime = 60; ... agar ($idLifetime) ( // Agar seans identifikatorining ishlash muddati o'rnatilgan bo'lsa, // sessiya boshlanganidan beri o'tgan vaqtni tekshiring yaratilgan yoki oxirgi regeneratsiya // (sessiya oʻzgaruvchisi boshlanish vaqti yangilangan oxirgi soʻrov vaqti) if (isset($_SESSION["starttime"])) ( if ($t-$_SESSION["starttime"] >= $ idLifetime) ( // Seans identifikatorining amal qilish muddati tugagan vaqt // Yangi identifikatorni yaratish session_regenerate_id(true); $_SESSION["starttime"] = $t; ) ) else ( // Seans endigina bo'lsa, biz shu erga kelamiz. yaratilgan // Seans identifikatorini yaratish vaqtini joriy vaqtga belgilang $_SESSION["starttime"] = $t; ) ) return true; )

Shunday qilib, yangi seans yaratishda (foydalanuvchi muvaffaqiyatli tizimga kirganida sodir bo'ladi), biz seans identifikatorining so'nggi avlodi vaqtini biz uchun saqlaydigan sessiya o'zgaruvchisi start vaqtini joriy server vaqtiga teng qiymatga o'rnatamiz. Keyinchalik, har bir so'rovda biz identifikatorning oxirgi avlodidan beri etarli vaqt (idLifetime) o'tganligini tekshiramiz va agar shunday bo'lsa, biz yangisini yaratamiz. Shunday qilib, agar identifikatorning belgilangan muddati davomida vakolatli foydalanuvchining cookie-faylini olgan tajovuzkor undan foydalanishga ulgurmasa, soxta so'rov server tomonidan ruxsatsiz deb hisoblanadi va tajovuzkor login sahifasiga o'tkaziladi. .

Eslatma: session_regenerate_id() funksiyasi chaqirilganda yangi seans identifikatori brauzer cookie-fayliga kiradi, u session_start() funksiyasiga o‘xshash yangi cookie-faylni yuboradi, shuning uchun biz cookie-faylni o‘zimiz yangilashimiz shart emas.

Agar biz seanslarimizni iloji boricha xavfsizroq qilishni istasak, identifikatorning ishlash muddatini bittasiga o'rnatish yoki hatto session_regenerate_id() funktsiyasini qavslardan olib tashlash va barcha tekshiruvlarni olib tashlash kifoya, bu har birida identifikatorning qayta tiklanishiga olib keladi. iltimos. (Men ushbu yondashuvning ishlashga ta'sirini sinab ko'rmadim va shuni aytishim mumkinki, session_regenerate_id(true) funksiyasi asosan 4 ta amalni bajaradi: yangi identifikator yaratish, sessiya cookie fayli bilan sarlavha yaratish, eskisini o'chirish va yaratish. yangi sessiya fayli).

Lirik chekinish: Agar troyan shu qadar aqlli bo'lib chiqsaki, u tajovuzkorga cookie-fayllarni yubormaydi, lekin cookie-faylni olgandan so'ng darhol oldindan tayyorlangan soxta so'rovni yuborishni tashkil qilsa, yuqorida tavsiflangan usul, ehtimol, buni amalga oshira olmaydi. bunday hujumdan himoya qiling, chunki troyan cookie-faylni qabul qilish va soxta so'rov yuborish o'rtasida deyarli hech qanday farq bo'lmaydi va hozirda seans identifikatori qayta tiklanmasligi ehtimoli yuqori.

Bitta brauzerda bir vaqtning o'zida bir nechta foydalanuvchi nomidan ishlash imkoniyati Men ko'rib chiqmoqchi bo'lgan oxirgi vazifa - bu bir nechta foydalanuvchilarning bir brauzerda bir vaqtning o'zida ishlash imkoniyati. Bu xususiyat, ayniqsa, foydalanuvchilarning bir vaqtning o'zida ishini taqlid qilish kerak bo'lganda, sinov bosqichida foydalidir va buni butun mavjud arsenaldan foydalanish yoki inkognito rejimida brauzerning bir nechta nusxalarini ochish o'rniga, sevimli brauzeringizda qilish tavsiya etiladi. .

Oldingi misollarimizda biz seans nomini aniq ko'rsatmadik, shuning uchun standart PHP nomi (PHPSESSID) ishlatilgan. Bu shuni anglatadiki, biz hozirgacha yaratgan barcha seanslar PHPSESSID nomi ostida brauzerga cookie faylini yuborgan. Shubhasiz, agar cookie nomi har doim bir xil bo'lsa, u holda bitta brauzerda bir xil nomdagi ikkita seansni tashkil qilishning hech qanday usuli yo'q. Ammo har bir foydalanuvchi uchun o'z seans nomimizdan foydalansak, muammo hal bo'lar edi. Keling, shunday qilaylik.

Funktsiya startSession($isUserActivity=true, $prefiks=null) ( ... agar (session_id()) rost bo'lsa; // Agar parametrlarda foydalanuvchi prefiksi o'tkazilgan bo'lsa, // buni o'z ichiga olgan noyob sessiya nomini o'rnating. prefiks, // aks holda barcha foydalanuvchilar uchun umumiy nom o'rnating (masalan, MYPROJECT) session_name("MYPROJECT".($prefiks ? "_".$prefiks: "")); ini_set("session.cookie_lifetime", 0); agar (! session_start()) false qaytarsa; ... )

Endi qo'ng'iroq qiluvchi skript startSession() funksiyasiga har bir foydalanuvchi uchun noyob prefiks o'tishiga ishonch hosil qilishgina qoladi. Buni, masalan, har bir so'rovning GET/POST parametrlarida prefiksni o'tkazish yoki qo'shimcha cookie orqali amalga oshirish mumkin.

Xulosa Xulosa qilib aytganda, men PHP seanslari bilan ishlash uchun funktsiyalarimizning to'liq yakuniy kodini, shu jumladan yuqorida muhokama qilingan barcha vazifalarni taqdim etaman.

Funktsiya startSession($isUserActivity=true, $prefiks=null) ( $sessionLifetime = 300; $idLifetime = 60; agar (session_id()) rost qaytarsa; session_name("MYPROJECT".($prefiks ? "_".$prefiks: "")); ini_set("session.cookie_lifetime", 0); agar (! session_start()) false qaytarsa; $t = time(); if ($sessionLifetime) (if (isset($_SESSION["so'nggi faollik"]) ) && $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; ) ) true return; ) function destroySession() (if (session_id()) ( session_unset(); setcookie(session_name(), session_id(), time() -60*60*24); session_destroy(); ) )

Umid qilamanki, ushbu maqola hech qachon sessiya mexanizmini chuqur o'rganmaganlar uchun biroz vaqtni tejaydi va PHP bilan endigina tanishishni boshlayotganlar uchun ushbu mexanizm haqida etarlicha ma'lumot beradi.

Sizga foydalanuvchi nomi va parol kerakmi?

Maqolalarni onlayn yuborish va yuborilgan maqolalar holatini tekshirish uchun siz ro'yxatdan o'tishingiz va hisobingizga kirishingiz kerak.

Taqdim etish uchun maqola tayyorlash uchun nazorat ro'yxati

Maqola taqdim etish jarayonining bir qismi sifatida mualliflar o'z maqolalari quyidagi fikrlarning barchasiga mos kelishini tekshirishlari kerak; agar ular ushbu talablarga javob bermasa, maqolalar mualliflarga qaytarilishi mumkin.

Maqola talablarga muvofiq tayyorlangan

Mualliflik huquqini topshirish shartlari

Mualliflar asarga mualliflik huquqini saqlab qoladilar va jurnalga asar bilan bir qatorda birinchi nashr qilish huquqini ham beradi, shu bilan birga uni Creative Commons Attribution License shartlariga muvofiq litsenziyalaydi, bu esa boshqalarga ushbu asarni asar muallifiga majburiy atribut va havola bilan tarqatish imkonini beradi. ushbu jurnaldagi asl nashrga.

Maxfiylik bayonoti

Ushbu jurnal veb-saytiga kiritilgan ismlar va elektron pochta manzillari faqat ushbu jurnal tomonidan belgilangan maqsadlar uchun ishlatiladi va boshqa maqsadlarda foydalanilmaydi yoki boshqa shaxs yoki yuridik shaxsga berilmaydi.

Tizimda ro'yxatdan o'tishdan oldin foydalanuvchi shaxsiy ma'lumotlarni qayta ishlash va saqlash siyosatiga rozi bo'ladi.

Muallif to'lovlari

Bo'shliqlar bilan 1500 belgi: 300.00 (RUB)

1 sahifa qo'lyozmani nashr etish (1500 belgi) - 300 rubl. Grafik materiallar / jadvallar alohida to'lanadi - 50 rubl / 1 dona. Muallifning nusxasi, shu jumladan Rossiya bo'ylab jo'natish, muallifning iltimosiga binoan to'lanadi - 400 rubl. Chet elga etkazib berish - 800 rubl. Materialni nashrga qabul qilish to'g'risidagi guvohnomani yuborish narxi 150 rublni tashkil qiladi.

Qo'shimcha ma'lumotlarning (mualliflarning to'liq ismi, ish joyi; sarlavha; referat; kalit so'zlar) ingliz tiliga tarjimasi har bir belgi uchun 0,5 rubl, shu jumladan bo'shliqlar.

Diqqat! elibrary.ru ma'lumotlariga ko'ra, 300 va undan ortiq iqtibosga ega bo'lgan mualliflar (nomzodlar va fan doktorlari) (o'z-o'zidan iqtiboslar ulushi 30% dan oshmasligi kerak) bepul nashr etiladi. Agar siz bepul nashr etish huquqiga ega bo'lsangiz, material yuborayotganda sharhlar maydonida iqtiboslar soni bilan kutubxona profilingizga havolani ko'rsating. Yig'ish uchun etkazib berish xarajatlari alohida to'lanadi.

Veb-sayt xavfsizligi sessiyalarni boshqarishga asoslangan. Foydalanuvchi xavfsiz saytga ulanganda, odatda foydalanuvchi nomi va parol ko'rinishida hisob ma'lumotlarini taqdim etadi. Veb-server qaysi foydalanuvchi allaqachon tizimga kirganligi yoki ular sahifadan sahifaga qanday o'tishini bilmaydi. Seans mexanizmi foydalanuvchilarning har safar yangi amalni bajarish yoki yangi sahifaga o'tish uchun parol kiritishiga to'sqinlik qiladi.

Asosan, sessiya boshqaruvi hozirda ulangan foydalanuvchi autentifikatsiya qilingan foydalanuvchi ekanligini ta'minlaydi. Ammo, afsuski, seanslar xakerlar uchun aniq nishonga aylandi, chunki ular autentifikatsiyani talab qilmasdan veb-serverga kirishga ruxsat berishi mumkin.

Foydalanuvchi autentifikatsiya qilingandan so'ng, veb-server unga seans identifikatorini beradi. Ushbu identifikator brauzerda saqlanadi va autentifikatsiya zarur bo'lganda almashtiriladi. Bu sizga takroriy login/parol kiritish jarayonlaridan qochish imkonini beradi. Bularning barchasi fonda sodir bo'ladi va foydalanuvchiga noqulaylik tug'dirmaydi. Har safar yangi sahifani ko'rganingizda foydalanuvchi nomingiz va parolingizni kiritgan bo'lsangiz, tasavvur qiling!

Ushbu maqolada men PHP-da seans identifikatorini himoya qilishning barcha usullarini aytib berishga harakat qilaman.

Cookie-fayllardan foydalanish Odatiy bo'lib, barcha seans ma'lumotlari, jumladan ID, cookie-faylga yuboriladi. Lekin bu har doim ham sodir bo'lavermaydi. Ba'zi foydalanuvchilar o'z brauzerlarida cookie-fayllarni o'chirib qo'yishadi. Bunday holda, brauzer URL manzilida sessiya identifikatorini o'tkazadi.

Bu erda identifikator aniq matnda uzatiladi, ma'lumot HTTP sarlavhasida yashirin bo'lsa, cookie orqali seansdan farqli o'laroq. Bundan himoyalanishning eng oddiy usuli, manzil satri orqali sessiya identifikatorini uzatishni taqiqlashdir. Buni Apache serveri .htaccess konfiguratsiya fayliga quyidagilarni yozish orqali amalga oshirish mumkin:

Php_flag session.use_only_cookies yoqilgan

Shifrlashdan foydalanish Agar saytingiz kredit karta raqamlari (Sony'dan salom) kabi nozik ma'lumotlarni qayta ishlashi kerak bo'lsa, siz SSL3.0 yoki TSL1.0 shifrlashdan foydalanishingiz kerak. Buning uchun cookie-faylni o'rnatishda xavfsiz parametr uchun true ni belgilashingiz kerak.

Agar siz seans parolini $_SESSION o'zgaruvchisida saqlasangiz (sql-dan foydalanish yaxshiroq), uni aniq matnda saqlamasligingiz kerak.

Agar ($_SESSION["parol"] == $userpass) ( // kod )

Yuqoridagi kod xavfsiz emas, chunki parol seans o'zgaruvchisida oddiy matn sifatida saqlanadi. Buning o'rniga md5 shifrlashdan foydalaning, shunga o'xshash:

Agar ($_SESSION["md5password"] == md5($userpass)) ( // kod )

Brauzer tekshiruvi Seansdan boshqa brauzerdan (kompyuterdan) foydalanish imkoniyatini oldini olish uchun HTTP sarlavhasi maydoniga foydalanuvchi agenti chekini kiritishingiz kerak:

Session_start(); agar (isset($_SESSION["HTTP_USER_AGENT"])) ( agar ($_SESSION["HTTP_USER_AGENT"] != md5($_SERVER["HTTP_USER_AGENT"])) ( // kod ) ) boshqacha ( $_SESSION["HTTP_USER_AGENT" ] = md5($_SERVER["HTTP_USER_AGENT"]); )

Seansning tugashi Seansning amal qilish muddatini, shuningdek, cookie-fayllarning amal qilish muddatini cheklang. Odatiy bo'lib, sessiya davomiyligi 1440 soniya. Ushbu qiymatni php.ini va .htaccess orqali o'zgartirishingiz mumkin. .htaccess uchun misol:

# Seansning ishlash muddati soniyalarda
php_value session.gc_maxlifetime 3600
# Cookie-ning ishlash muddati soniyalarda
php_value session.cookie_lifetime 3600

IP-manzil bo'yicha bog'lash Ba'zi hollarda (har doim ham emas), siz IP-manzil bo'yicha ulanishingiz kerak. Asosan foydalanuvchilar soni cheklangan va statik IP-ga ega bo'lganda. Tekshirish ruxsat etilgan IP manzillar ro'yxatiga asoslanishi mumkin,

Include("ip_list.php"); //$ip_white_list = massiv ("admin1" => "111.222.333.444", "admin2" => "555.666.777.888"); if(!empty(array_search($_SERVER["REMOTE_ADDR"],$ip_white_list))) ( header("Joylashuv: admin.php"); ) else ( "ACCESS DENY!"; ) aks-sado

Yoki har bir so'rov uchun IP-manzil bo'yicha (faqat statik IP uchun):

If(isset($_SESSION["ip"]) va $_SESSION["ip"] == $_SERVER["REMOTE_ADDR"]) ( header("Joylashuv: admin.php"); ) else ( session_unset(); $ _SESSION["ip"] = $_SERVER["REMOTE_ADDR"]; )

Shuni bilishingiz kerakki, xakerlikdan butunlay qochish mumkin emas. Siz faqat ma'lum bo'lgan har qanday usul bilan bu buzishni iloji boricha qiyinlashtirishingiz mumkin. Biroq, bunday himoya bilan ularning hayotini murakkablashtirmaslik uchun qonuniy foydalanuvchilaringizni ham unutmasligingiz kerak.

Ushbu maqola 2009 yilda yozilgan va bizning eng mashhur postlarimizdan biri bo'lib qolmoqda. Agar siz PHP va MySQL haqida ko'proq ma'lumotga ega bo'lishni istasangiz, bu sizga katta qiziqish uyg'otadi.

QAYD: Ushbu maqola PHP 4.2 yoki undan keyingi versiyalarida ishlash uchun yangilangan!

Yaqinda men bir guruh odamlar bilan kichik loyiha ustida ishlash imkoniyatiga ega bo'ldim. Biz boshidanoq o'sha elektron pochta xabari hammani xabardor qilish uchun etarli emasligini aniqlagan edik, shuning uchun menga loyiha uchun kichik veb-sayt yaratish topshirildi. Unda oddiy xabarlar paneli, jamoaning qolgan a'zolari foydalanishi uchun hujjatlar va boshqa fayllarni yuklashimiz mumkin bo'lgan joy va turli jamoa a'zolari uchun aloqa ma'lumotlari bo'lishi mumkin.

Ushbu funktsiyalarning ko'pchiligi ishlashi uchun men saytning tegishli qismlariga kirishdan oldin foydalanuvchilarning tizimga kirishi kerakligini bilardim. Menga kerak bo'lgan narsa, foydalanuvchilarga saytga kirish uchun foydalanuvchi identifikatori uchun ro'yxatdan o'tishga imkon beradigan tizim edi, so'ngra mening aralashuvimsiz darhol ushbu identifikatordan foydalanishi mumkin edi.

Ushbu maqolada men birinchi yarmida foydalanuvchi ro'yxatdan o'tish jarayonidan boshlab o'zim ishlab chiqqan tizim haqida umumiy ma'lumot beraman. Ikkinchi yarmida men saytning o'ziga e'tibor qarataman, u foydalanuvchilardan qanday qilib tizimga kirishni talab qiladi va keyin tashrif davomida tizimga kirganlik holatini saqlab qoladi. Men PHP da seanslarni boshqarish funksiyalaridan foydalanishga alohida e'tibor beraman. Oxir-oqibat, siz o'zingizning shunga o'xshash tizimingizni amalga oshirish uchun zarur bo'lgan barcha ma'lumotlarga ega bo'lishingiz kerak.

Ushbu maqola davomida men sizda PHP tili, PHP skriptiga ma'lumot yuborish uchun shakllardan foydalanish va MySQL ma'lumotlar bazasi bilan o'zaro ishlashda PHP dan qanday foydalanish mumkinligi haqida asosiy ma'lumotga ega ekanligingizni taxmin qilaman. Agar bulardan biri siz uchun begona tushunchalar bo'lsa, mening oldingi maqolamni o'qishdan boshlashingiz kerak, .

Birinchi qism: Ro'yxatdan o'tish jarayoni Ro'yxatdan o'tish shakli

Foydalanuvchilarning kirish uchun ro'yxatdan o'tishlarini talab qiladigan sayt qurishni boshlashning tabiiy joyi bu ro'yxatdan o'tish jarayonining o'zi. Kutilganidek, oddiy veb-asoslangan shakl yordam beradi. Bu qanday ko'rinishda bo'ladi:

Va bu shakl uchun kod:




Yangi foydalanuvchi ro'yxatdan o'tish



Yangi foydalanuvchi ro'yxatdan o'tish shakli

* talab qilinadigan maydonni bildiradi


Maqsad aniq bo'lsa, men sizga accesscontrol.php kodini aytib beraman. Ikkita qulay faylni kiritish bilan boshlang: