Sesiuni

HTTP este un protocol fără stare, dar aproape toate aplicațiile trebuie să păstreze o stare între cereri, de exemplu, conținutul unui coș de cumpărături. Pentru aceasta se folosește o sesiune. Să vedem

  • cum se utilizează sesiunile
  • cum să evităm conflictele de denumire
  • cum se stabilește expirarea

Atunci când se utilizează sesiuni, fiecare utilizator primește un identificator unic numit ID de sesiune, care este transmis într-un modul cookie. Acesta servește drept cheie pentru datele sesiunii. Spre deosebire de modulele cookie, care sunt stocate pe partea browserului, datele de sesiune sunt stocate pe partea serverului.

Noi configurăm sesiunea în configurare, alegerea timpului de expirare este importantă.

Sesiunea este gestionată de obiectul Nette\Http\Session, pe care îl obțineți trecându-l folosind injecția de dependență. În prezentatori, pur și simplu apelați $session = $this->getSession().

Instalare și cerințe

Pornirea sesiunii

În mod implicit, Nette va porni automat o sesiune în momentul în care începem să citim din ea sau să scriem date în ea. Pentru a porni manual o sesiune, utilizați $session->start().

PHP trimite antetele HTTP care afectează memoria cache atunci când începe sesiunea, a se vedea session_cache_limiter, și, eventual, un cookie cu ID-ul sesiunii. Prin urmare, este întotdeauna necesar să se pornească sesiunea înainte de a trimite orice ieșire către browser, în caz contrar va fi lansată o excepție. Prin urmare, dacă știți că o sesiune va fi utilizată în timpul redării paginii, porniți-o manual înainte, de exemplu în prezentator.

În modul dezvoltator, Tracy pornește sesiunea, deoarece o folosește pentru a afișa barele de redirecționare și de cereri AJAX în bara Tracy.

Secțiunea

În PHP pur, stocarea datelor de sesiune este implementată ca o matrice accesibilă prin intermediul unei variabile globale $_SESSION. Problema este că, în mod normal, aplicațiile sunt formate din mai multe părți independente și, dacă toate au la dispoziție doar același array, mai devreme sau mai târziu va avea loc o coliziune de nume.

Nette Framework rezolvă problema prin împărțirea întregului spațiu în secțiuni (obiecte Nette\Http\SessionSection). Fiecare unitate utilizează apoi propria secțiune cu un nume unic și nu mai pot apărea coliziuni.

Obținem secțiunea de la managerul de sesiune:

$section = $session->getSection('unique name');

În prezentator este suficient să se apeleze getSession() cu parametrul:

// $this este prezentator
$section = $this->getSession('unique name');

Existența secțiunii poate fi verificată prin metoda $session->hasSection('unique name').

Secțiunea în sine este foarte ușor de lucrat cu ajutorul metodelor set(), get() și remove():

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

// citirea unei variabile, returnează null dacă aceasta nu există
echo $section->get('userName');

// eliminarea variabilei
$section->remove('userName');

Este posibil să se utilizeze ciclul foreach pentru a obține toate variabilele din secțiune:

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

Cum se stabilește expirarea

Expirarea poate fi setată pentru secțiuni individuale sau chiar pentru variabile individuale. Putem permite ca autentificarea utilizatorului să expire în 20 de minute, dar să ne amintim în continuare conținutul unui coș de cumpărături.

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

Al treilea parametru al metodei set() este utilizat pentru a seta expirarea variabilelor individuale:

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

Nu uitați că timpul de expirare al întregii sesiuni (a se vedea configurația sesiunii) trebuie să fie egal sau mai mare decât timpul stabilit pentru secțiunile sau variabilele individuale.

Anularea expirării setate anterior poate fi realizată prin metoda removeExpiration(). Ștergerea imediată a întregii secțiuni va fi asigurată prin metoda remove().

Evenimentele $onStart, $onBeforeWrite

Obiectul Nette\Http\Session are evenimentele $onStart a $onBeforeWrite, astfel încât puteți adăuga callback-uri care sunt apelate după ce sesiunea începe sau înainte ca aceasta să fie scrisă pe disc și apoi terminată.

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

Gestionarea sesiunilor

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

start(): void

Pornește o sesiune.

isStarted(): bool

A început sesiunea?

close(): void

Încheie sesiunea. Sesiunea se încheie automat la sfârșitul scriptului.

destroy(): void

Încheie și șterge sesiunea.

exists(): bool

Cererea HTTP conține un modul cookie cu un ID de sesiune?

regenerateId(): void

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

getId(): string

Returnează ID-ul sesiunii.

Configurație

Configuram sesiunea în configurare. Dacă scrieți o aplicație care nu utilizează un container DI, utilizați aceste metode pentru a o configura. Ele trebuie apelate înainte de a porni sesiunea.

setName(string $name): static

Definește numele cookie-ului care este utilizat pentru a transmite ID-ul sesiunii. Numele implicit este PHPSESSID. Acest lucru este util în cazul în care executați mai multe aplicații diferite pe același site.

getName(): string

Returnează numele cookie-ului de sesiune.

setOptions(array $options)static

Configurează sesiunea. Este posibil să setați toate directivele sesiunii PHP (în format camelCase, de exemplu, scrieți savePath în loc de session.save_path) și,
de
asemenea, readAndClose.

setExpiration(?string $time)static

Stabilește timpul de inactivitate după care expiră sesiunea.

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

Stabilește parametrii pentru cookie-uri. Puteți modifica valorile implicite ale parametrilor în configuration.

setSavePath(string $path)static

Stabilește directorul în care sunt stocate fișierele de sesiune.

setHandler(\SessionHandlerInterface $handler)static

Definește gestionarul personalizat, consultați documentația PHP.

Siguranța mai întâi

Serverul presupune că comunică cu același utilizator atâta timp cât cererile conțin același ID de sesiune. Sarcina mecanismelor de securitate este de a se asigura că acest comportament funcționează cu adevărat și că nu există nicio posibilitate de a înlocui sau fura un identificator.

De aceea, Nette Framework configurează în mod corespunzător directivele PHP pentru a transfera ID-ul de sesiune numai în cookie-uri, pentru a evita accesul din JavaScript și pentru a ignora identificatorii din URL. Mai mult, în momentele critice, cum ar fi autentificarea utilizatorului, generează un nou ID de sesiune.

Funcția ini_set este utilizată pentru configurarea PHP, dar, din păcate, utilizarea sa este interzisă la unele servicii de găzduire web. Dacă este cazul dumneavoastră, încercați să cereți furnizorului dumneavoastră de găzduire să vă permită această funcție sau cel puțin să configureze serverul său în mod corespunzător.

versiune: 4.0