Sesiuni

HTTP este un protocol fără stare, însă aproape orice aplicație are nevoie să păstreze starea între cereri, de exemplu conținutul coșului de cumpărături. Tocmai pentru aceasta servesc sesiunile. Vom arăta,

  • cum să utilizați sesiunile
  • cum să preveniți conflictele de nume
  • cum să setați expirarea

La utilizarea sesiunilor, fiecare utilizator primește un identificator unic numit ID de sesiune, care este transmis într-un cookie. Acesta servește drept cheie pentru datele sesiunii. Spre deosebire de cookie-uri, care sunt stocate pe partea browserului, datele din sesiune sunt stocate pe partea serverului.

Sesiunea o setăm în configurație, importantă fiind în special alegerea timpului de expirare.

Gestionarea sesiunii este responsabilitatea obiectului Nette\Http\Session, la care ajungeți solicitându-l prin injecție de dependențe. În presentere, este suficient să apelați $session = $this->getSession().

Instalare și cerințe

Pornirea sesiunii

Nette, în setarea implicită, pornește automat sesiunea în momentul în care începem să citim sau să scriem date în ea. Manual, sesiunea se pornește folosind $session->start().

PHP trimite la pornirea sesiunii antete HTTP care afectează stocarea în cache, vezi session_cache_limiter, și eventual și un cookie cu ID-ul sesiunii. De aceea, este necesar să porniți întotdeauna sesiunea înainte de a trimite orice ieșire către browser, altfel se va arunca o excepție. Deci, dacă știți că în timpul randării paginii se va utiliza sesiunea, porniți-o manual înainte, de exemplu în presenter.

În modul de dezvoltare, Tracy pornește sesiunea, deoarece o utilizează pentru afișarea barelor cu redirecționări și cereri AJAX în Tracy Bar.

Secțiuni

În PHP pur, stocarea datelor sesiunii este realizată ca un array accesibil prin variabila globală $_SESSION. Problema este că aplicațiile sunt compuse în mod obișnuit dintr-o serie de părți independente reciproc și dacă toate au la dispoziție doar un singur array, mai devreme sau mai târziu va apărea o coliziune de nume.

Nette Framework rezolvă problema împărțind întregul spațiu în secțiuni (obiecte Nette\Http\SessionSection). Fiecare unitate utilizează apoi propria secțiune cu un nume unic și nicio coliziune nu mai poate avea loc.

Obținem secțiunea din sesiune:

$section = $session->getSection('nume-unic');

În presenter este suficient să folosim getSession() cu parametru:

// $this este Presenter
$section = $this->getSession('nume-unic');

Existența secțiunii poate fi verificată cu metoda $session->hasSection('nume-unic').

Cu secțiunea însăși se lucrează apoi foarte ușor folosind metodele set(), get() și remove():

// scriere variabilă
$section->set('userName', 'franta');

// citire variabilă, returnează null dacă nu există
echo $section->get('userName');

// anulare variabilă
$section->remove('userName');

Pentru a obține toate variabilele dintr-o secțiune, se poate utiliza bucla foreach:

foreach ($section as $key => $val) {
	echo "$key = $val";
}

Setarea expirării

Pentru secțiuni individuale sau chiar variabile individuale se poate seta expirarea. Putem astfel lăsa autentificarea utilizatorului să expire după 20 de minute, dar în același timp să păstrăm conținutul coșului.

// secțiunea expiră după 20 de minute
$section->setExpiration('20 minutes');

Pentru setarea expirării variabilelor individuale servește al treilea parametru al metodei set():

// variabila 'flash' va expira după 30 de secunde
$section->set('flash', $message, '30 seconds');

Nu uitați că timpul de expirare al întregii sesiuni (vezi configurarea sesiunii) trebuie să fie egal sau mai mare decât timpul setat pentru secțiunile sau variabilele individuale.

Anularea expirării setate anterior se realizează cu metoda removeExpiration(). Anularea imediată a întregii secțiuni este asigurată de metoda remove().

Evenimentele $onStart, $onBeforeWrite

Obiectul Nette\Http\Session are evenimente $onStart și $onBeforeWrite, deci puteți adăuga callback-uri care se declanșează după pornirea sesiunii sau înainte de scrierea ei pe disc și închiderea ulterioară.

$session->onBeforeWrite[] = function () {
	// scriem datele în sesiune
	$this->section->set('basket', $this->basket);
};

Gestionarea sesiunii

Prezentare generală a metodelor clasei Nette\Http\Session pentru gestionarea sesiunii:

start(): void

Pornește sesiunea.

isStarted(): bool

Sesiunea este pornită?

close(): void

Închide sesiunea. Sesiunea se închide automat la sfârșitul rulării scriptului.

destroy(): void

Închide și șterge sesiunea.

exists(): bool

Cererea HTTP conține un cookie cu ID-ul sesiunii?

regenerateId(): void

Generează un nou ID de sesiune aleatoriu. Datele rămân păstrate.

getId(): string

Returnează ID-ul sesiunii.

Configurație

Sesiunea o setăm în configurație. Dacă scrieți o aplicație care nu utilizează containerul DI, pentru configurare servesc aceste metode. Trebuie apelate înainte de pornirea sesiunii.

setName (string $name): static

Setează numele cookie-ului în care se transmite ID-ul sesiunii. Numele standard este PHPSESSID. Este util în cazul în care pe același site web rulați mai multe aplicații diferite.

getName(): string

Returnează numele cookie-ului în care se transmite ID-ul sesiunii.

setOptions (array $options)static

Configurează sesiunea. Se pot seta toate directivele de sesiune PHP (în format camelCase, de ex. în loc de session.save_path scriem savePath) și, de asemenea, readAndClose.

setExpiration (?string $time)static

Setează perioada de inactivitate după care sesiunea expiră.

setCookieParameters (string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null)static

Setarea parametrilor pentru cookie. Valorile implicite ale parametrilor le puteți modifica în configurație.

setSavePath (string $path)static

Setează directorul unde se salvează fișierele cu sesiuni.

setHandler (\SessionHandlerInterface $handler)static

Setarea unui handler personalizat, vezi documentația PHP.

Securitatea înainte de toate

Serverul presupune că comunică în continuare cu același utilizator, atâta timp cât cererile sunt însoțite de același ID de sesiune. Sarcina mecanismelor de securitate este să asigure că acest lucru se întâmplă într-adevăr și că nu este posibilă furtul sau substituirea identificatorului.

Nette Framework configurează, prin urmare, corect directivele PHP, astfel încât ID-ul sesiunii să fie transmis doar în cookie, să fie inaccesibil pentru JavaScript și să ignore eventualii identificatori din URL. În plus, în momente critice, cum ar fi autentificarea utilizatorului, generează un nou ID de sesiune.

Pentru configurarea PHP se utilizează funcția ini_set, pe care, din păcate, unele hostinguri o interzic. Dacă este și cazul hosterului dvs., încercați să discutați cu el pentru a vă permite funcția sau cel puțin pentru a configura serverul.

versiune: 4.0