Računalniki Windows internet

Seje. Podroben opis delovanja in razlaga mehanizma. Zaščita ID-ja seje v PHP Organizacija inurl knjiga gostov php phpsessid

Seje v PHP ali kako se podatki o uporabniku ali stranki, ki je vstopil na spletno mesto, shranijo pri krmarjenju med stranmi spletnega mesta brez večjih težav. Lekcija je zelo pomembna. Pomemben za ustvarjanje 95 % spletnih mest.

Kaj je seja v php

Seje se uporabljajo za shranjevanje informacij o začasnih podatkih (na primer, da je uporabnik vstopil na spletno mesto) pri krmarjenju med stranmi istega mesta. Pri uporabi sej se podatki shranijo v začasne datoteke na strežniku.
Najpogosteje se seje (pa tudi piškotki) uporabljajo pri ustvarjanju spletnih trgovin, forumov, oglasnih desk, socialna omrežja, blogi in drugi viri. Priročnost sistema sej je v shranjevanju začasnih informacij prijavljenega uporabnika / stranke, podatki o katerih so določen čas v hitrem dostopu. Seja ima naravni datum poteka - dokler se brskalnik ne zapre. Če zaprete samo stran, bodo podatki o uporabniku/kupcu še vedno na voljo, ko odprete spletno mesto.

Logika seje

Seja (ali seja) je neke vrste začasno shranjevanje podatkov. Takoj vas opozarjam, da je vredno shraniti majhno količino podatkov. Na primer, prijava in geslo uporabnika, ki se prijavi, ali njegova serijska številka v bazi podatkov.

Primer dela
1. Uporabnik vnese uporabniško ime in geslo ter vstopi na spletno mesto
2. Podatki s prijavo in geslom se shranijo v seji ene od strani spletnega mesta:

mapa index.php

Začetek_seje (); // vsaka datoteka, v kateri želite uporabiti podatke o seji, mora vsebovati ukaz "start session" na začetku kode

$ prijava = "skrbnik";
$ geslo = "prepust";
$ _SESSION ["prijava"] = $ prijava; // shrani spremenljivko, ki vsebuje prijavo
$ _SESSION ["password"] = $ geslo; // shrani spremenljivko, ki vsebuje geslo

3. Ko greste na drugo stran spletnega mesta, bodo na voljo tudi ti podatki:

mapa example.php(ali katera koli druga stran)

Echo "Vaša prijava". $ _ SESSION ["prijava"]; // prikaže "Vaša prijava je skrbnik", čeprav na tej strani nismo zabeležili podatkov!
Glej, preprosto je!

4. Če želite počistiti podatke seje, je dovolj:

mapa example.php

Začetek_seje (); // znova "zaženi sejo".

Nenastavljen ($ _ SESSION ["prijava"]); // tako je bila spremenljivka neregistrirana ali "uničena"
echo "Vaša prijava". $ _ SESSION ["prijava"]; // prikaže "Vaša prijava". Ker smo ga uničili v zadnji vrstici, tudi podatkov ni.

Session_destroy (); // uniči sejo. Vsi podatki, vključno z $_SESSION ["password"], so izginili. Ko bo zahtevano, se prikaže napaka
Na splošno je takšen prenos podoben Metoda POST, le da vam ni več treba pisati veliko nepotrebne kode, vsi podatki, ki se prenašajo s strani na stran, pa so shranjeni v začasnih datotekah na strežniku. Ponovno bi morale seje vsebovati majhne količine podatkov, zato so primerne za shranjevanje uporabniškega imena/gesla, nakupovalnega vozička in drugih majhnih količin.

Posredovanje vrednosti ali matrike s sejo PHP

V seji lahko napišete ne samo niz, temveč tudi niz podatkov. Samo ne pretiravajte z velikostjo matrike, saj bo vse to vplivalo na zmogljivost in zaseden prostor na strežniku.

Ponovno uporabljamo določeno začetna stran index.php

Začetek_seje ();

$ r = matrika ("ena", "dva", "tri");

$ _SESSION ["arr"] = $ r;

Na stran, kjer je vse prikazano
Podatke smo shranili v sejo in sledimo povezavi na drugo stran, kjer bomo prikazali vse podatke.

Prejemnik datoteke, stran test.php kjer odpremo matriko

Začetek_seje ();
print_r ($ _ SESSION ["arr"]);
// bo izpisal
/*
Niz
=> ena
=> dva
=> tri
*/
?>
Morda boste želeli osvežiti vadnico o. Na splošno bi moralo biti vse jasno.

Druge funkcije za delo s sejami

session_unregister (niz)- seja pozabi vrednost podane globalne spremenljivke;
session_destroy ()- seja je uničena (če je uporabnik na primer zapustil sistem s pritiskom na gumb za odjavo);
session_set_cookie_params (int življenjska doba [, pot niza [, domena niza]])- s to funkcijo lahko nastavite, kako dolgo bo trajala seja, tako da nastavite unix_timestamp, ki določa čas smrti seje.

Seznam funkcij za delo s sejami (session) v php
session_cache_expire - Vrne potek trenutnega predpomnilnika
session_cache_limiter - Pridobite in / ali nastavite trenutno omejitev predpomnilnika
session_commit - vzdevek za session_write_close ()
session_decode - dekodira podatke seje iz niza
session_destroy - uniči vse podatke, registrirane za sejo
session_encode - šifrira trenutne podatke seje kot niz
session_get_cookie_params - Pridobite parametre piškotka seje
session_id - pridobi in/ali nastavi ID trenutne seje
session_is_registered - določa, ali je spremenljivka registrirana v seji
session_module_name - Pridobite in / ali namestite modul za trenutno sejo
session_name - dobi in / ali nastavi ime trenutne seje
session_regenerate_id - Spremeni trenutni ID seje z novo ustvarjenim
session_register - registrira eno ali več spremenljivk za trenutno sejo
session_save_path - pridobi in / ali nastavi pot za shranjevanje trenutne seje
session_set_cookie_params - nastavi parametre piškotka seje
session_set_save_handler - nastavi funkcije shranjevanja sej na ravni uporabnika
session_start - inicializira podatke seje
session_unregister - Odstrani registracijo spremenljivke iz trenutne seje
session_unset - sprosti vse spremenljivke seje
session_write_close - Zapiše podatke o seji in konec seje

Primeri sej

Števec ogledov strani med sejo. Ilustrativen primer dela. Vendar se bo po zaprtju brskalnika odštevanje začelo znova.

Števec obiskov ene strani v eni seji

// Preprost primer uporabe sej brez piškotkov.
session_name ("test");
začetek_seje ();
$ _SESSION ["count"] = @ $ _ SESSION ["count"] + 1;
?>

Števec


V trenutni seji dela z brskalnikom ste odprli to stran
čas (s).
Zaprite brskalnik, da ponastavite ta števec.
Kliknite tukaj za osvežitev strani!
Z vsakim prehodom se bo števec povečal za 1)

Hvala za pozornost! Vso srečo pri vaših prizadevanjih!

Seje so pravzaprav zelo preproste. Samo razumeti morate, čemu so namenjeni in kako so urejeni. Odgovorimo najprej na prvo vprašanje.
Morda veste, da spletni strežnik ne podpira stalna povezava z naročnikom, vsaka zahteva pa se obdela kot nova, brez komunikacije s prejšnjimi.

To pomeni, da ne morete niti slediti zahtevam istega obiskovalca, niti shraniti spremenljivk zanj med ogledi. posamezne strani... Seje so bile izumljene za reševanje teh dveh težav.
Pravzaprav so seje, na kratko, mehanizem, ki vam omogoča edinstveno identifikacijo brskalnika in ustvari datoteko za ta brskalnik na strežniku, ki shranjuje spremenljivke seje.

Ne bom podrobno opisoval potrebe po takem mehanizmu. Gre za primere, kot so nakupovalni voziček v spletni trgovini, avtorizacija, pa tudi ne povsem trivialne težave, kot je na primer zaščita interaktivnih delov strani pred vsiljeno pošto.

Načeloma je precej enostavno narediti lasten analog sej, ki ni tako funkcionalen kot vgrajeni PHP, a v bistvu podoben. O piškotkih in bazi podatkov.

Ko zahtevamo skript, pogledamo, ali je piškotek prišel z določenim imenom. Če piškotkov ni, ga nastavite in v bazo podatkov napišite novo vrstico z uporabniškimi podatki. Če obstajajo piškotki, beremo iz baze podatkov. Z še eno zahtevo izbrišemo stare zapise iz baze in zdaj imamo pripravljen mehanizem seje. Sploh ni težko. Vendar pa obstaja nekaj odtenkov, zaradi katerih je boljša uporaba vgrajenega mehanizma seje.

Najprej morate nekako prepoznati brskalnik. Če želite to narediti, mu morate dati edinstveni identifikator in zahtevajte, da ga pošljete z vsako zahtevo. Sram me je priznati, a ko sem prvič izvedel za seje, sem pomislil, da je to nekakšen poseben mehanizem, nek nov način komunikacije med brskalnikom in strežnikom - "sessions". Da se identifikator seje posreduje na nek poseben način. Toda razočaranje je bilo kruto ...

Seje uporabljajo standardne, dobro znane metode prenosa podatkov. Pravzaprav drugih preprosto ni.
Identifikator je običajna spremenljivka. Privzeto je njegovo ime PHPSESSID.
PHP-jeva naloga je, da ga pošlje brskalniku, da ga vrne z naslednjo zahtevo. Iz že omenjenega razdelka s pogostimi vprašanji je jasno, da je spremenljivko mogoče posredovati le na dva načina: v piškotkih ali v zahtevi POST/GET.
PHP uporablja obe možnosti.

Za to sta odgovorni dve nastavitvi v php.ini:

session.use_cookies - če je enak 1, potem PHP posreduje identifikator piškotkom, če je 0 - potem ne.
session.use_trans_sid, če je enak 1, potem ga PHP posreduje in doda URL-ju in obrazcem, če je 0 - potem ne.

Te in druge parametre seje lahko spremenite na enak način kot druge nastavitve PHP - v datoteki php.ini, pa tudi z ukazom ini_set () ali v konfiguracijskih datotekah spletnega strežnika

Če je omogočen samo prvi, potem na začetku seje (ob vsakem klicu session_start ()) piškotki so nastavljeni odjemalcu. Brskalnik pravilno vrne ta piškotek z vsako naslednjo zahtevo, PHP pa ima identifikator seje. Težave se začnejo, če piškotki brskalnika se ne vrne. V tem primeru, ne da bi prejel piškotke z identifikatorjem, bo PHP ves čas začel novo sejo in mehanizem ne bo deloval.

Če je omogočena samo druga, potem piškotki niso nastavljeni. In kar se zgodi, je, zaradi česar je pravzaprav vredno uporabiti vgrajeni mehanizem seje. Ko skript opravi svoje delo in je stran v celoti oblikovana, PHP vse to pregleda in vsaki povezavi in ​​vsakemu obrazcu doda ID seje. Izgleda nekako takole:

Indeks

se spremeni v

Indeks

in obrazcem je dodano skrito polje

Teoretično lahko v naših domačih sejah z vami o piškotkih in bazi sami ročno dodelite prenos id-ja vsem povezavam - in potem bodo naše lastne seje delovale ne glede na piškotke. Ampak, vidite – bolj prijetno je, ko to dela nekdo drug? ;-)

Obe možnosti sta privzeto omogočeni v zadnjih različicah PHP. Kako PHP to obravnava? Kuharica je vedno razstavljena. Povezave se samodejno dokončajo samo, če PHP ni našel piškotkov z ID-jem seje. Ko uporabnik med to sejo prvič obišče spletno mesto, se mu namestijo piškotki in dodajo se povezave. Ob naslednji zahtevi, če so piškotki podprti, PHP vidi piškotke in preneha dopolnjevati povezave. Če piškotki ne delujejo, potem PHP še naprej pravilno dodaja id povezavam in seja ni izgubljena.
Uporabniki s piškotki bodo dolgo povezavo z ID-jem videli samo enkrat.

Ko je prenos identifikatorja končan. Zdaj je treba nanjo povezati datoteko s podatki na strani strežnika. PHP bo to naredil namesto nas. Dovolj je samo napisati:

začetek_seje ();
$ _SESSION ["test"] = "Pozdravljeni svet!" ;

PHP bo testno spremenljivko zapisal v datoteko, povezano s to sejo.

Tukaj je zelo pomembna točka.

Niz $ _SESSION- poseben.
V njem so pravzaprav spremenljivke, ki jih želimo dati na voljo v različnih skriptah.
Če želite spremenljivko postaviti v sejo, jo preprosto dodelite elementu matrike $_SESSION.
Za pridobitev njegove vrednosti je dovolj, da se sklicujete na isti element. Primer bo spodaj.

Zbiranje smeti - odstranjevanje zastarelih PHP datoteke naredi tudi sam. Pa tudi kodiranje podatkov in kup drugih potrebnih stvari. Zaradi te skrbi je delo s sejami zelo enostavno.
Tukaj smo pravzaprav prišli do primera dela sej.
Primer je zelo majhen:

začetek_seje ();

odmev "Posodobili ste to stran"... $ _SESSION ["števec"] ++. "enkrat.";
odmev "
nadgradnja ";
?>

Preverimo, ali imamo spremenljivko števca v seji, če ne, jo ustvarimo z vrednostjo 0, nato pa izpišemo njeno vrednost in jo povečamo za eno. Povečana vrednost bo zapisana v sejo in naslednjič, ko bo skript poklican, bo imela spremenljivka vrednost 1 itd. Vse je zelo preprosto.

Če želite imeti dostop do spremenljivk seje na kateri koli strani spletnega mesta, morate na samem začetku VSAKE datoteke napisati SAMO ENO (!) vrstico, v kateri potrebujemo seje:

začetek_seje ();

začetek_seje ();
če ($ _SESSION ["avtorizirano"]<> 1 ) {
glava ("Lokacija: /auth.php");
izhod;
}

Odstranjevanje spremenljivk iz seje. Če imate register_globals = off, potem samo napišite

nenastavljen ($ _ SESSION ["var"]);

Če ne, potem v bližini z njim morate napisati:

session_unregister ("var");

Zelo pomembno je razumeti, za kaj je treba seje uporabiti in za kaj ne.

Najprej ne pozabite, da se seje lahko uporabljajo samo, ko jih uporabnik potrebuje, ne pa da bi ga ovirali. Konec koncev se lahko identifikatorja kadar koli znebi!
Na primer, ko preveri, ali oseba izpolni obrazec in ne skripta, se uporabnik sam zanima, da seja deluje - sicer ne bo mogel oddati obrazca! Toda za omejitev števila zahtev za skript seja ni več primerna - zlonamerni skript preprosto ne bo vrnil identifikatorja.

Drugič. Pomembno je jasno razumeti dejstvo, da je seja seja dela s spletnim mestom, kot jo razume oseba. Prišel, delal, zaprl brskalnik - seja se je končala. Kot filmska seja. Če želite videti še enega - kupite novo vstopnico. Začnite novo sejo. Za to obstaja tudi tehnična razlaga. Zagotovljeno je, da mehanizem seje deluje le, dokler se brskalnik ne zapre. Navsezadnje piškotki morda ne bodo delovali za odjemalca in v tem primeru bodo seveda vse povezave, dopolnjene z identifikatorjem, izginile, ko bo ta zaprt.

Vendar pa je sejo mogoče izgubiti, ne da bi zaprli brskalnik. Zaradi omejitev, obravnavanih v tem članku, motor seje ne more zaznati, kdaj je uporabnik zaprl brskalnik. Za to se uporablja časovna omejitev - vnaprej določen čas, po katerem menimo, da je uporabnik zapustil spletno mesto. Privzeto je ta parameter 24 minut.

Če želite podatke o uporabniku hraniti dlje časa, uporabite piškotke in po potrebi bazo podatkov na strežniku. Zlasti tako delujejo vsi priljubljeni sistemi avtorizacije:

Ob identifikaciji uporabnika se seja začne in vanjo se prenese znak avtorizacije.
- Če je treba uporabnika "zapomniti", se mu nastavi piškotek, ki ga identificira.
- Ko uporabnik naslednjič vstopi na spletno mesto, mora za prijavo vnesti geslo ali pa ga sistem sam prepozna po prej nastavljenih piškotkih in seja se začne. Nova seja, namesto da bi nadaljevala staro.

Tretjič, ni vredno začeti sej neselektivno, za vse, ki vstopajo na spletno mesto. To bo ustvarilo popolnoma nepotrebno obremenitev. Ne uporabljajte sej za malenkosti - na primer v pultih. Kar spilog kliče seje, se seveda šteje na podlagi statistike klicev in ne z uporabo mehanizma sej, podobnega PHP.

Poleg tega vzemimo iskalnik, ki indeksira vaše spletno mesto. Če iskalni robot ne podpira piškotkov, potem bo PHP povezavam privzeto dostavil PHPSESSID, kar morda ni preveč prijetno za iskalnik, ki po govoricah tako ali tako ne daje prednost dinamičnim povezavam, tukaj pa na splošno z vsakim klicem - nov naslov!

Če se seje uporabljajo za omejevanje dostopa do zaprtega dela spletnega mesta, potem je vse le iskalnik in ga ne bi smeli indeksirati. Če morate isto stran prikazati tako pooblaščenim kot nepooblaščenim uporabnikom, bo tukaj pomagal tak trik - začeti sejo samo tistim, ki so vnesli geslo, ali tistim, ki so sejo že začeli.

Če želite to narediti, na začetku vsake strani, namesto samo session_start () pišemo:

if (isset ($ _ REQUEST [ime_seje ()])) session_start ();

tako začnemo sejo samo tistim, ki so poslali identifikator.
V skladu s tem ga je treba uporabniku poslati prvič - v trenutku avtorizacije.

Če sta ime in lopa pravilna - napiši session_start () !

Najpogostejše napake, ki jih PHP daje pri poskusu dela s sejami, so:
dva izmed njih,

Opozorilo: piškotka seje ni mogoče poslati - glave so že poslane
Opozorilo: Omejevalnika predpomnilnika seje ni mogoče poslati - glave so že poslane

zaradi istega razloga, je rešitev opisana v tem dejstvu

Opozorilo: odprtje (/ tmp \ sess_SID, O_RDWR) ni uspelo: ni takšne datoteke ali imenika (2) v full_script_path na številki vrstice

prej je bila videti kot

Opozorilo: Podatkov o seji (datoteke) ni bilo mogoče napisati. Preverite, ali je trenutna nastavitev session.save_path pravilna (/ tmp) ,

če je preveden iz angleščine, podrobno razloži težavo: pot, podana v php.ini, do imenika, kamor so zapisane datoteke seje, ni na voljo. To napako je najlažje odpraviti. Samo napišite imenik, ki obstaja in je zapisljiv, npr.

session.save_path = c: \ windows \ temp

In po tem ne pozabite znova zagnati Apache.

Kot se je izkazalo, človeška inteligenca nima meja, zato moram pojasniti:
tretje sporočilo o napaki (imenika ni mogoče najti) bo NEDOSTOPNO vodilo do prvih dveh, ker se sporočilo o napaki izpiše v brskalnik in za njim ne morete uporabiti glav. Zato ne hitite iskati prezgodnjega zaključka, ampak najprej napišite pravilno pot!

Naslednja najpogostejša težava pri obravnavi sej je težka zapuščina register_globals. NE dajajte skriptnih spremenljivk enakih imen kot indeksi matrike $_SESSION!

Z register_globals = on bodo vrednosti prepisali druga drugo in boste zmedeni.

Če ne deluje, vendar se tudi ne prikažejo nobena sporočila, dodajte dve vrstici na samem začetku skripta, ki sta odgovorni za prikaz VSEH napak na zaslonu - povsem možno je, da so napake, vendar jih preprosto ne vidite njim.

ini_set ("display_errors", 1);
poročanje o napaki (E_ALL);

ali si oglejte napake v dnevniku napak. Na splošno tema o prikazovanju sporočil o napakah presega obseg tega članka, zato se prepričajte, da jih vsaj vidite. V tem razdelku si lahko preberete nekaj več podrobnosti o odpravljanju težav.

Če ste prepričani, da ni napak, a dani primer vseeno ne deluje, potem je možno, da PHP ne omogoča prenosa id-ja preko url-a, in piškotki iz nekega razloga ne delujejo.
Poglejte, kaj imate s piškotki.

Na splošno, če vaše seje "ne delujejo", najprej poskusite ročno prenesti identifikator seje, torej ustvarite povezavo in ji dodelite identifikator:

začetek_seje ();
če (! isset ($ _ SESSION ["števec"])) $ _SESSION ["števec"] = 0;
odmev "Posodobili ste to stran"... $ _SESSION ["števec"] ++. "enkrat.

nadgradnja ";
?>

Ko to počnete, se prepričajte, da direktiva session.use_only_cookies ni omogočena, kar preprečuje, da bi PHP sprejel ID seje, če je bil posredovan prek URL-ja.

Če ta primer ne deluje, je težava bodisi v banalnem tipkarske napake(polovica "problemov" s sejami izvira iz napačno črkovanega imena spremenljivke) ali v prestari različici PHP: podpora za seje se je pojavila v različici 4.0 in matrika $ _SESSION- v 4.1 (Prej uporabljeno $ HTTP_SESSION_VARS).

Če deluje, je težava v piškotkih. Sledenje - kakšne piškotke strežnik postavi v brskalnik, ali jih brskalnik vrne. Iskanje je zelo uporabno pri ogledu izmenjave glave HTTP med brskalnikom in strežnikom.

Razlaga delovanja piškotkov je zunaj obsega tega in toliko besedila, vendar se vsaj prepričajte, da strežnik pošlje piškotke z identifikatorjem, brskalnik pa se vrne. In medtem ko identifikatorji sovpadajo med seboj =)
Nastavitev piškotkov bi morala izgledati tako

Set-Cookie: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6;

Set-Cookie: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; pot = /

(če zahtevate skript, ki ni iz korenskega imenika)
Odgovor strežnika bi moral izgledati tako

Piškotek: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6

Piškotek: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; b = b

če brskalnik vrne piškotke, ki niso ID seje.

Če primer od tukaj deluje, vaša lastna koda pa ne, potem težava očitno ni v sejah, ampak v algoritmu. Poiščite, kje ste izgubili spremenljivko, prenesite primer od tu korak za korakom, razhroščite svoj skript.

Druga težava se lahko pojavi, če uporabljate preusmeritev glave ali navigacijo JavaScript.
Dejstvo je, da PHP samodejno doda identifikator seje samo povezavam obrazca
, vendar tega ne stori za glave, javascript, meta oznake.

Zato morate identifikator dodati ročno, na primer tako:

header ("Lokacija: /script.php?". ime_seje (). "=". id_sesije ());

Prav tako je zelo redka in popolnoma nerazumljiva, od kod prihaja težava, težava v tem, da ima nastavitev session.save_handler drugo vrednost kot datoteke. Če temu ni tako, popravite.

  • Mehanizem seje poleg piškotkov pošilja tudi glave, ki prepovedujejo predpomnjenje strani (isti omejevalnik predpomnilnika). Za html je to pravilno in potrebno. Ko pa poskušate poslati datoteko s skriptom, ki preverja avtorizacijo, Internet Explorer zavrne prenos. Prav zaradi tega naslova. Pokliči
    session_cache_limiter ("zasebno");
    morate rešiti težavo pred začetkom seje.
  • Nenavadno, vendar v nizu $ _SESSION ne morete uporabljati številčnih indeksov - $ _SESSION [1], $ _SESSION ["10"]- seje ne bodo delovale.
  • Nekje med 4.2 in 5.0 ni bilo mogoče nastaviti session.use_trans_sid z ini_set ()... Od 5.0 je že spet možno.
  • Pred različico 4.3.3 piškotki PHP je pošiljal piškotke le, če zahteva ni vsebovala identifikatorja na začetku seje. Zdaj se piškotki pošiljajo ob vsakem klicu session_start

    Če imate še kakšno vprašanje ali vam kaj ni jasno - dobrodošli pri nas

Od vsega začetka so vsi s pokom sprejeli PHP, a takoj, ko so začeli ustvarjati dovolj velike projekte v tem jeziku, so se razvijalci soočili z novo težavo – v PHP-ju ni bilo koncepta globalnih spremenljivk! To pomeni, da je bil skript izveden, ustvarjena stran je poslana odjemalcu in vsi viri, ki jih uporablja ta skript, so bili uničeni. Za ponazoritev recimo, da sta na istem mestu dve strani, index.php in dothings.php. Viri za te strani so videti takole:

index.php dothings.php

Če izvedete ta dva skripta, bomo na prvi strani videli napis "Dodeljen sem bil index.php", druga stran pa bo prazna.

Razvijalci spletnih mest so brez zadržkov začeli uporabljati piškotke za shranjevanje globalnih spremenljivk na strani odjemalca. Postopek je izgledal nekako takole: uporabnik pride na domačo stran spletnega mesta, izvede nekaj dejanj in vsi podatki v zvezi s tem uporabnikom, ki bodo morda potrebni na drugih straneh spletnega mesta, bodo shranjeni v njegovem brskalniku v obliki piškotka. Ta metoda ima precej resne pomanjkljivosti, zaradi katerih so mnogi razvijalci naenkrat obrnili hrbet PHP. Uporabnika moramo na primer pooblastiti, da mu omogoči dostop do omejenih (ali samo njegovih) delov spletnega mesta. Uporabniku boste morali poslati piškotek, ki bo služil kot njegov kasnejši identifikator na spletnem mestu. Ta pristop postane zelo okoren in neprijeten, takoj ko začne spletno mesto zbirati vse več informacij o vedenju uporabnikov, saj je treba vse informacije, poslane uporabniku, po možnosti kodirati, da jih ni mogoče ponarediti. V zadnjem času je bilo s ponarejanjem piškotka mogoče "zlagati" več kot en klepet, včasih pa celo priti na pošto nekoga drugega. Poleg tega na svetu še vedno obstajajo čudni ljudje, katerih brskalnik ne podpira piškotkov.

Ne bom se spuščal v tehnološka vprašanja strukture mehanizma sej, ampak bom le opisal, kako pravilno delati s sejami v PHP.

Kako delati s sejami?

Če preizkusite primere iz članka (ali svoje skripte) na katerem koli komercialnem gostovanju, pri delu s sejami ne bi smelo biti težav. Če strežnik nastavite sami (naj bo to pravi strežnik ali emulator), se lahko pojavijo napake z naslednjo vsebino:

"Opozorilo: odprtje (/ var / state / php / sess_6f71d1dbb52fa88481e752af7f384db0, O_RDWR) ni uspelo: ni takšne datoteke ali imenika (2)".

To samo pomeni, da je vaš PHP napačno konfiguriran. To težavo lahko rešite tako, da napišete pravilno pot (do obstoječega imenika), da shranite seje v datoteko php.ini in znova zaženete strežnik.

Vsak skript, ki bo uporabljal spremenljivke (podatke) iz sej, mora vsebovati naslednjo vrstico:

Začetek_seje ();

Ta ukaz pove strežniku, da dana stran potrebuje vse spremenljivke, ki so povezane z danim uporabnikom (brskalnikom). Strežnik vzame te spremenljivke iz datoteke in jih da na voljo. Zelo pomembno je, da odprete sejo, preden se kateri koli podatki pošljejo uporabniku; v praksi to pomeni, da je priporočljivo poklicati funkcijo session_start () na samem začetku strani, na primer:

Začetek_seje (); ?> ... Če želite nastaviti imenik, v katerem bodo shranjene datoteke seje, uporabite funkcijo session_save_path (): session_save_path ($ _ SERVER ["DOCUMENT_ROOT"]. "/ Session"); začetek_seje ();

Ko se seja začne, lahko nastavite globalne spremenljivke. Ko dodelite vrednost kateremu koli polju v matriki $ _SESSION, se spremenljivka z istim imenom samodejno registrira kot spremenljivka seje. Ta niz je na voljo na vseh straneh, ki uporabljajo sejo. Na primer, analizirajmo program:

index.php Vse v redu. Seja je bila naložena! Pojdimo skozi, poglejmo, kaj je tam: dothings.php

Ko se te datoteke izvajajo zaporedno, bo prvi skript "index.php" ustvaril naslednji rezultat:

Vse v redu. Seja je bila naložena! Pojdimo skozi, poglejmo, kaj je tam:

In drugi "dothings.php" je ta:

Vprašali so me na index.php

Spremenljivka $ a je zdaj na voljo na vseh straneh tega spletnega mesta, ki so začele seje.

Druge uporabne funkcije in tehnike za delo s sejami:

  • nenastavljen ($ _ SESSION ["a"])- seja "pozabi" vrednost spremenljivke, ki jo je nastavila seja;
  • session_destroy ()- seja je uničena (če je uporabnik na primer zapustil sistem s pritiskom na gumb "izhod");
  • session_set_cookie_params (int življenjska doba [, pot niza [, domena niza]])- s to funkcijo lahko nastavite, kako dolgo bo seja "živela" z nastavitvijo unix_timestamp, ki določa čas, ko seja "umre". Privzeto seja "živi", dokler odjemalec ne zapre okna brskalnika.
  • session_write_close ()- snemanje spremenljivk seje in zapiranje. To je potrebno za odpiranje spletnega mesta v novem oknu, če stran izvaja dolgotrajno obdelavo in je blokirala datoteko seje za vaš brskalnik.

Primeri

Zdaj pa se obrnimo na praktično uporabo mehanizma seje. Tukaj si bomo ogledali nekaj dokaj preprostih, a uporabnih primerov.

Pooblastilo uporabnika

Na konferencah o spletnem programiranju se nenehno postavljajo vprašanja o avtorizaciji uporabnikov s pomočjo PHP sej. Mehanizem za avtorizacijo uporabnikov v sistemu z uporabo sej je z varnostnega vidika precej dober (glej razdelek).

Naš primer bo sestavljen iz treh datotek: index.php, authorize.php in secretplace.php. Datoteka index.php vsebuje obrazec, kamor bo uporabnik vnesel svoje uporabniško ime in geslo. Ta obrazec bo posredoval podatke v datoteko authorize.php, ki bo v primeru uspešne avtorizacije uporabniku omogočila dostop do datoteke secretplace.php in sicer prikazala sporočilo o napaki.

Primeri: index.php Vnesite svoje geslo

Vpiši se:
geslo:
avtorize.php stran ... glava ("Lokacija: secretplace.php"); izhod; )) // če je bilo kaj narobe, bo uporabnik prejel // sporočilo o napaki. ?> Vnesli ste napačno geslo! secretplace.php Zdravo,, ste na skrivni strani !!! :)

Varnost

Tako lahko identifikator prenesemo z ene strani (PHP skript) na drugo (do naslednjega klica z naše strani), kar pomeni, da lahko ločimo vse obiskovalce strani. Ker je identifikator seje zelo veliko število (128 bitov), ​​praktično ni možnosti, da bo šlo za brutalno silo. Zato ima napadalec naslednje možnosti:

  • na uporabnikovem računalniku je trojanec, ki krade številke sej;
  • Napadalec ujame promet med uporabnikovim računalnikom in strežnikom. Seveda obstaja varen (šifriran) protokol SSL, vendar ga ne uporabljajo vsi;
  • sosed je prišel do računalnika našega uporabnika in ukradel številko seje.

Takšne situacije, ki temeljijo na dejstvu, da nekdo nekomu nekaj ukrade, na splošno niso v pristojnosti programerja. Za to bi morali poskrbeti skrbniki in uporabniki sami.

Vendar pa je PHP pogosto lahko zaveden. Oglejmo si možne točke vdora v programu za avtorizacijo uporabnikov:

  • Datoteka authorize.php - poskus uganiti geslo z uporabo skripta tretje osebe;
  • Datoteka secretplace.php je poskus prevare programa z vnosom vrednosti spremenljivke $logged_user v naslovno vrstico brskalnika, na primer:
    "http://www.yoursite.ru/secretplace.php? logged_user = heker"

Tako sta v našem programu dobro vidni dve "luknji", ena je majhna in ni posebej opazna, druga pa preprosto ogromna, skozi katero večina hekerjev pleza tja, kjer jim ni treba.

Kako "zakrpati" luknjo številka 1?

Ne bomo napisali na tone kode za blokiranje naslova IP ipd., ampak samo preverimo, od kod prihaja zahteva, oziroma s katere strani je prišla zahteva, če je katera stran z našega spletnega mesta, potem je vse v redu, ampak v vseh drugih primerih ga ne bomo spustili. Popravimo datoteko authorize.php:

authorize.php V2 stran ... glava ("Lokacija: secretplace.php"); izhod; )))?> Vnesli ste napačno geslo!
Kako se znebiti "luknje" številka 2?

Recimo, da imate spletno stran, kjer se lahko vsak smrtnik registrira za objavo na forumu. Seveda imajo na forumu nekateri uporabniki (administratorji, moderatorji) več možnosti kot drugi, na primer lahko izbrišejo sporočila drugih uporabnikov. Raven dostopa uporabnika shranite v sejo v spremenljivko $ user_status, kjer $ user_status = 10 ustreza popoln dostop sistemu. Napadalec, ki pride na spletno mesto, se mora samo na običajen način registrirati in nato dodati v naslovno vrstico brskalnika ? status_uporabnika = 10... Torej imate novega administratorja na vašem forumu!

V bistvu lahko katero koli spremenljivko skripta nastavite preko naslovna vrstica tako, da skriptu za polnim naslovom preprosto dodate vprašaj in ime spremenljivke z njeno vrednostjo. Popravimo našo kodo, da se temu izognemo:

secretplace.php V2 spremenljivka ni nastavljena ($ _ SESSION ["logged_user"]); // odpremo sejo session_start (); / * ne morete samo iti na to stran ... če uporabniško ime ni registrirano, ga preusmerimo na stran index.php, da vnesete prijavo in geslo ... tukaj lahko dejansko naredite veliko, za na primer, zapomnite si uporabnikov IP in ga po tretjem poskusu dostopa do datotek blokirajte. * / if (! isset ($ _ SESSION ["logged_user"])) (glava ("Location: index.php"); izhod;)?> Zdravo,, ste na skrivni strani! Rezultati

Mehanizem seje je precej kul lastnost PHP jezik... Seje so preproste, zelo prilagodljive za uporabo. Mimogrede, obstaja ena, redko dokumentirana priložnost PHP seje(na voljo od različice 4.0.3) - v sejah je mogoče shraniti ne samo spremenljivke, ampak tudi predmete.

Primeri

?>
// Samodejno vstavljanje SID-jev v povezave. ini_set ("session.use_trans_sid", true); začetek_seje (); ?> Klikni tukaj!
Klikni tukaj !!

// Primer dela s sejami. začetek_seje (); // Če je bila stran pravkar obiskana, ponastavite števec. če (! isset ($ _ SESSION ["count"])) $ _SESSION ["count"] = 0; // Povečaj števec v seji. $ _SESSION ["count"] = $ _SESSION ["count"] + 1; ?>

Števec

čas (s).
Zaprite brskalnik, da ponastavite števec.
"target =" _blank "> Odprite okno podrejenega brskalnika.
// Preprost primer uporabe sej brez piškotkov. session_name ("test"); začetek_seje (); $ _SESSION ["count"] = @ $ _ SESSION ["count"] + 1; ?>

Števec

V trenutni seji dela z brskalnikom ste odprli to strančas (s).
Zaprite brskalnik, da ponastavite ta števec.
?"> Kliknite tukaj za osvežitev strani!

Seje so preprost način za shranjevanje informacij za posamezne uporabnike z edinstvenim ID-jem seje. To lahko uporabite za obstojno stanje med zahtevami strani. ID-ji seje se običajno pošljejo brskalniku prek piškotka seje in se uporabljajo za pridobivanje razpoložljivih podatkov seje. Odsotnost ID-ja seje ali piškotka seje pove PHP-ju, da ustvari novo sejo in ustvari nov ID seje.

Seje uporabljajo preprosto tehnologijo. Ko je seja ustvarjena, bo PHP bodisi dobil obstoječo sejo z uporabo posredovanega identifikatorja (običajno iz piškotka seje) ali, če ni bilo posredovano nič, bo ustvarjena nova seja. PHP bo naselil superglobal $_SESSION z informacijami o seji po začetku seje. Ko PHP zapusti, bo samodejno serializiral vsebino superglobala $ _SESSION in oddal v shranjevanje z uporabo upravljalnika seje za snemanje seje.

PHP privzeto uporablja notranji upravljalnik datotek za shranjevanje sej, ki je nastavljen v spremenljivki session.save_handler INI. Ta upravljalnik shrani podatke na strežnik v imenik, podan v konfiguracijski direktivi session.save_path.

Seje lahko zaženete ročno s funkcijo session_start ()... Če je direktiva session.auto_start nastavljena na 1, se bo seja samodejno začela na začetku zahteve.

Seja se običajno konča, ko PHP konča z izvajanjem skripta, vendar jo lahko prekinete tudi ročno s funkcijo session_write_close ().

Opozorilo

Pozor

Komentar:

Seje z uporabo datotek (privzeto v PHP) blokirajo datoteko seje takoj po odprtju seje s funkcijo session_start () ali posredno z navedbo session.auto_start. Po blokiranju noben drug skript ne more dostopati do iste datoteke seje, dokler se ne zapre ali ko se skript konča ali ko se pokliče funkcija. session_write_close ().

To je najverjetneje težava za spletna mesta, ki močno uporabljajo AJAX in dajejo več sočasnih zahtev. Najpreprostejši način za rešitev te težave je klic funkcije session_write_close () takoj ko so narejene vse zahtevane spremembe v seji, po možnosti bližje začetku skripta. Uporabite lahko tudi drug mehanizem seje, ki podpira sočasnost.

Ne morem ugotoviti zakaj, vendar sem poskusil vse / google odgovore .. Nisem našel ničesar. Tukaj je situacija:

Localhost koda

rezultat:

Zaporedni session_id () na straneh aplikacije in pri osveževanju strani. $ _COOKIE ["PHPSESSID"] se ujema z ID-jem seje ()

Neposredni strežnik

Začetek_seje (); echo session_id (); print_r ($ _ COOKIE ["PHPSESSID"]);

rezultat:

session_id () se spremeni ob vsaki zahtevi, ponovnem nalaganju strani ali obisku druge strani. $ _COOKIE ["PHPSESSID"] je NULL / prazen. Ista koda se uporablja na vrhu strani. nobene druge vsebine.

Ta težava mi je povzročila pravi glavobol, kakšna konfiguracija strežnika ali napaka bi to lahko povzročila? Zakaj je piškotek PHPSESSID prazen, verjamem, da je zato, ker se povezani session_id () ponastavi tudi pri vsaki zahtevi?

Fantje prosim za kakršnokoli pomoč!

EDIT: Na svojem lokalnem oddaljenem strežniku sem naredil preprosto testno datoteko s 3 vrsticami. Ni povezano z mojo kodo. $ _COOKIE ["PHPSESSID"] je še vedno prazen in nov session_id () se zgodi na pravem gostitelju ob vsaki posodobitvi.

error_reporting NASTAVI NA VSE. Dobim to na gostitelju v živo:

Obvestilo: Nedefiniran indeks: PHPSESSID v /home/vivaplug/public_html/dev/wp-content/plugins/test.php v vrstici 5

Glave za Google Chrome

LOKALNI GOSTITELJ

URL zahteve: http: //localhost/wp-content/plugins/test.php Metoda zahteve: GET Statusna koda: 200 OK Zahteva za naslove vir pogleda Sprejmi: besedilo / html, aplikacija / xhtml + xml, application / xml; q = 0,9, slika / webp, * / *; q = 0,8 Sprejmi kodiranje: gzip, deflate, sdch Sprejmi-jezik: en-US, en; q = 0,8 Nadzor predpomnilnika: brez predpomnilnika Povezava: ohranjanje življenj Piškotek: PHPSESSID = 68b7m4arpsacks4rsaet3m Gostitelj: localhost Pragma: brez predpomnilnika Uporabniški agent: Mozilla / 5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML, kot Gecko) Chrome / 30.0.1599.101 Safari / 537.36 Response Headersview, brez predpomnilnika cache, must-revalidate, post-check = 0, pre-check = 0 Povezava: Keep-Alive Content-Type: text / html Datum: torek, 5. november 2013 07:10:51 GMT Poteče: četrtek, 19. november 1981 08 : 52: 00 GMT Keep-Alive: časovna omejitev = 5, največ = 100 Pragma: brez predpomnilnika Strežnik: Apache / 2.4.4 (Win32) PHP / 5.4.16 Transfer-Encoding: chunked X-Powered-By: PHP / 5.4 .16

ODSTRANITE STREŽNIK

URL zahteve: http: //vivaplugins.com/dev/wp-content/plugins/test.php Metoda zahteve: GET Status Code: 200 OK Zahteva Headersview vir Sprejmi: text / html, application / xhtml + xml, application / xml; q = 0,9, slika / webp, * / *; q = 0,8 Sprejmi kodiranje: gzip, deflate, sdch Sprejmi-jezik: en-US, en; q = 0,8 Nadzor predpomnilnika: max-age = 0 Povezava: ohrani- živ Host: vivaplugins.com User-Agent: Mozilla / 5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML, kot Gecko) Chrome / 30.0.1599.101 Safari / 537.36 Response Headersview: št. Caetro vir -cache, must-revalidate, post-check = 0, pre-check = 0 Content-Encoding: gzip Content-Type: text / html Datum: torek, 5. november 2013 07:07:49 GMT Pragma: strežnik brez predpomnilnika: Napredno gostovanje s strani http://www.unixy.net/varnish Transfer-Encoding: chunked Vary: Accept-Encoding Via: 1.1 varnish X-Cache: HIT X-Cache-Hits: 2 X-Cacheable: DA X-Powered-By : PHP / 5.4.20 X-lak: 1984840969 1984839805