PHPPamokos.lt


12. Vartotojai, prisijungimai ir sesijos

Rimtesni tinklalapiai turi turėti savo autorizacijos mechanizmą. Kad lankytojai galėtų registruotis, prisijungti ir gauti tam tikras paslaugas ar funkcijas, kurios neprieinamos neregistruotiems vartotojams. Kaip tai daroma PHP kalboje - aptarsime šiame skyrelyje.

Iš esmės, yra du būdai, kaip saugoti vartotojų prisijungimo sesijas: tai yra "sausainiukai" (cookies) bei paprastos PHP sesijos. Pradžioje papasakosime būtent apie sesijas.

Sesijos sukūrimas ir panaudojimas

Visas darbas su vartotojų sesijomis susideda iš keturių etapų:

  • Sesijos sukūrimas;
  • Sesijos kintamųjų užpildymas;
  • Sesijos kintamųjų panaudojimas;
  • Sesijos užbaigimas.

Kad panaudotumėte su sesijomis susijusias galimybes, pačioje skripto pradžioje turite pradėti sesiją: session_start();

Viskas, tiesiog paprasta funkcija be parametrų. Svarbu ją iškviesti anksčiau, negu yra į ekraną išvedamas bet koks tekstas, kitaip PHP išmes klaidą ir neleis tęsti skripto vykdymo. Ideliausiame variante, kaip sakiau, ši funkcija kviečiama pačioje skripto pradžioje - pirmoje eilutėje.

Taigi, sesija iškviesta, ir galima ją naudoti. Kiekvienai vartotojo sesijai serveryje yra sukuriamas kintamųjų masyvas, kuris saugomas tik tos sesijos gyvavimo metu. Dėl to, lankytojui pereinant nuo puslapio prie puslapio, galima atsekti, kas tai per vartotojas, kokios jo teisės, kokius puslapius jis jau aplankęs ir t.t.

Visa tai atliekama, įrašant duomenis į specialų sesijos masyvą $_SESSION. Tiesiog masyvo elementams priskiriame reikšmes.

$_SESSION['vartotojo_role'] = "1";
// pažymi, kad vartotojo rolė yra pirma (pvz, administratorius)
$_SESSION['puslapiai']++;
// pažymi, kad lankytojas aplankė dar vieną puslapį (+1)

Masyvas $_SESSION su išsaugotomis reikšmėmis yra prieinamas visiems PHP skriptams, kol tas vartotojas neatsijungia nuo sistemos ir neužbaigia savo sesijos. Arba kol sesijos laikas nesibaigia - turbūt, buvote su tuo susidūrę kaip vartotojai, kai internete prisijungę palikdavote kokį puslapį, ir po valandos jūsų paprašydavo prisijungti iš naujo.

Kai vartotojas atsijungia nuo sistemos, reikia jo sesiją būtinai panaikinti. Kitaip gali kilti problemų: prie to paties kompiuterio atsisėdęs kitas žmogus prieis prie to vartotojo sesijos be slaptažodžio. Panaikinimas atliekamas su dviem funkcijomis - session_unset() ir session_destroy() be parametrų:

session_unset(); // išvalo visus kintamuosius
session_destroy(); // panaikina pačią sesiją
 

Sesijos panaudojimo pavyzdys - autorizacijos mechanizmas

Pažiūrėkime į konkretų pavyzdį. Sakykime, jūs turite savo nedidelę turinio valdymo sistemą, ir jums reikia padaryti, kad prie jos galėtų prisijungti tik administratorius su tam tikru vartotoju ir slaptažodžiu. Prisijungimo forma gali atrodyti maždaug taip:

Iš šios prisijungimo formos į PHP skriptą perduodami trys formos parametrai-kintamieji: login, password ir submit. O formos kintamųjų perdavimo metodas yra POST. Tada sutrumpintas PHP skripto tekstas gali atrodyti taip:

session_start();
$error = ""; // klaidos tekstas - bendru atveju šis kintamasis tuščias
if ($_POST['submit'] == "Prisijungti") {
  // jeigu paspaustas mygtukas "Prisijungti"
  if ($_POST['login'] == "admin" && $_POST['password'] == "admin123") {
    $_SESSION['username'] = "admin";
  } else {
    $error = "Neteisingi prisijungimo duomenys";
  }
}
if ($_SESSION['username'] == "admin") {
  echo "Sveiki, jums prieinamos administratoriaus funkcijos...";
  // parodomas administratoriaus meniu
} else {
  echo "<form> ... </form>"; // užkraunama visa prisijungimo forma
  if ($error != "") { echo $error; }
}

Iš karto galiu pakomentuoti, kad šis pavyzdys yra labai supaprastintas, reali vartotojų sesijų sistema turi būti sudėtingesnė, nes reikia atsižvelgti į daug niuansų. Pvz, nepatartina slaptažodžių saugoti atvirai PHP skriptuose, nes juos gali pamatyti bet kas, turintis priėjimą prie web-serverio. Bendru atveju, vartotojų duomenys turi būti saugomi duomenų bazėje, o slaptažodis užkoduodas tam skirta funkcija ar algoritmu.

 

Kitas pavyzdys

Kaip kitą pavyzdį paimsime bet kokį puslapį, kuriame reikia patikrinti, ar vartotojas jau prisijungęs. Tiesą pasakius, tai dažna praktika, ir būtent taip darysime mūsų būsimame praktikos projekte (taip taip, nepamiršau, jis jau artėja). Sakykime, kad turime failą page.php:

session_start();
if (!isset($_SESSION['username'])) {
  header('Location: index.php');
  exit;
}
echo '<h1>Puslapis</h1>...';

Čia yra keli nauji jums dalykai. Visų pirma, funkcija isset() - ji skirta tiesiog patikrinimui, ar kintamasis egzistuoja ir turi kokią nors reikšmę. Ir prieš ją esantis šauktukas reiškia neiginį - galima tai skaityti kaip "nėra reikšmės". Mūsų atveju, jei sesijos kintamojo nėra - tai reiškia vartotojas neprisijungęs ir jį reikia perkelti į prisijungimo formą.

Kitas dalykas - pats perkėlimas, jis daromas su funkcija header(). Ji šiaip skirta bet kokiai antraštei (header) perduoti į naršyklę, bet vienas iš dažnesnių panaudojimų - perkėlimas į kitą puslapį. Vietoje index.php galite įrašyti savo norimą skriptą.

Ir galiausiai komanda exit, kuri tiesiog užbaigia skripto vykdymą.

Tokiu būdu, jeigu sesija egzistuoja ir kintamasis $_SESSION['username'] apibrėžtas, tai tada tas header-exit blokas nebus vykdomas, ir skriptas tiesiog parodys reikalingą informaciją, kuri nurodyta žemiau po tuo bloku. Būtent to mums ir reikia.

Kaip papildomą patobulinimą, sesijos patikrinimą galime iškelti į atskirą skriptą, kad jis "nesimaišytų" kiekviename PHP faile ir jo nereikėtų kopijuoti.

session.php:
session_start();
if (!isset($_SESSION['username'])) {
  header('Location: index.php');
  exit;
}
page.php:
include('session.php');
echo '<h1>Puslapis</h1>...';
 

Sesijos galiojimo laikas

Kaip jau minėjau, gan dažna problema - žmogus palieka kompiuterį kuriam laikui, o po to grįžęs, randa pasibaigusią sesiją, t.y. yra jo vartotojas atjungiamas nuo puslapio. Nuo ko tai priklauso? Nuo sesijos galiojimo laiko parametro, kuris yra nustatomas per PHP konfigūraciją. Per daug jums gilintis nereikia, bet pravartu žinoti, kad yra toks failiukas php.ini, kuriame yra visi nustatymai susiję su PHP veikimu web-serveryje. Jei naudojate XAMPP serverį lokaliai, tai to failiuko pilnas adresas būtų c:/xampp/php/php.ini - galite jį atidaryti su kokiu Notepad ar kitu teksto redaktoriumi ir pasižiūrėti, kokios ten reikšmės. Ten viskas paprasta - nustatymas, lygybės ženklas, ir jo reikšmė. Ir taip eilutė po eilutės. Kabliataškis eilutės pradžioje reiškia kad ta eilutė skirta komentarams ir nebus apdorojama.

Mums tame failiuke yra įdomus vienas konkretus parametras pavadinimu session.gc_maxlifetime - jis nusako, kiek sekundžių trunka viena sesija, t.y. po kiek laiko neaktyvaus vartotojo sesija bus panaikinta.

Kaip matote, nustatytas parametras yra 1440 sekundžių, kas reiškia 24 minutes - būtent tiek trunka neaktyvi sesija, bet šį parametrą galite keisti savo nuožiūra. Jei norite tai padaryti - tiesiog paredaguokite šią reikšmę, išsaugokite ir uždarykite php.ini failą, ir tada perkraukite XAMPP serverį, paspausdami Stop-Start prie Apache.

 

Darbas su cookies

Trumpai paminėsime ir tai, kaip veikia COOKIES. Visų pirma, kas tai yra ir kuo skiriasi nuo sesijų? Jie turi beveik identišką veikimą, bet yra vienas esminis skirtumas: sesijos saugomos serveryje, o cookies - vartotojo kompiuteryje. Kitaip tariant, kai vartotojas uždaro naršyklę ar tą konkretų puslapį, tai sesija serveryje išlieka tik tiek laiko, kiek yra nustatyta pagal mūsų minėtą session.gc_maxlifetime, o cookie šiuo atveju lieka žmogaus kompiuteryje ir galios neribotą laiką - na, arba tiek, kiek mes nustatėme, kol žmogus neperinstaliuos naršyklės/kompiuterio arba nepaspausk rankiniu būdu "Delete all cookies".

Cookies dažniausiai naudojami žmogaus prisiminimui ilgalaikiu laikotarpiu - pvz kai prie prisijungimo funkcijos yra varnelė "Prisiminti mane" tai tada tam tikri duomenys įrašomi į cookie, ir tada žmogus, grįžęs į puslapį kad ir po savaitės, prijungiamas automatiškai. Dėl to, beje, nerekomenduojama tokią varnelę pažymėti svetimame kompiuteryje.

Kitas cookie panaudojimas - žmogaus pasirinkimų saugojimas ilgesniam laikotarpiui. Kartais visai malonu, kai sugrįžti į puslapį ir jis prisimena, kokį batų dydį nešioji ar koks tavo el.paštas, kad nereikėtų vesti iš naujo. Aišku, yra ir kita medalio pusė - asmeninių duomenų saugumas ir privatumas, kai kurie žmonės piktinasi, kai pamato pvz kad Google rodo reklamas būtent pagal tai, kokius laiškus jie skaito. Ginčytis galima ilgai, bet pakalbėkime apie techninę dalį.

Cookies, kaip ir sesijos, veikia principu kintamasis-reikšmė. Tik nereikia jokių session_start(), ir konkretus cookie yra sukuriamas ne paprastu priskyrimu, o su specialia funkcija setcookie().

setcookie($name, $value, time()+86400*30, "/");

Funkcija turi keturis parametrus:

  • Kintamojo vardas
  • Kintamojo reikšmė
  • Iki kurio laiko cookie turi galioti - time() + sekundės
  • Kokiame puslapio kataloge cookie galioja - / reiškia visame projekte

Ir tada cookie iš PHP prieinamas per masyvą $_COOKIE - viskas veikia analogiškai kaip su masyvu $_SESSION:

echo $_COOKIE['username'];

Tik skirtumas nuo sesijų toks, kad negalime priskirti naujos reikšmės per $_COOKIE = xxx, tai neveiks - turime iš naujo kviesti setcookie su tuo pačiu kintamojo pavadinimu ir nauja reikšme.

Ir galiausiai - kaip panaikinti cookie: daromi du veiksmai. Pirmiausia, su PHP funkcija unset() yra naikinamas pats masyvo kintamasis, o tada kviečiama funkcija setcookie su tuščia reikšme ir galiojimo laiku, nustatytu į praeitį, pvz valanda atgal. Tada naršyklė automatiškai panaikina visus cookie, kurių galiojimo laikas pasibaigęs.

unset($_COOKIE[$cookie_name]);
setcookie($cookie_name, '', time() - 3600);


(c) 2015-2018. Visais klausimais kreipkitės povilas@laraveldaily.com