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()
.
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țisavePath
în loc de session.save_path
) și,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.