Sessionök
A HTTP egy állapot nélküli protokoll, azonban szinte minden alkalmazásnak szüksége van az állapot megőrzésére a kérések között, például a bevásárlókosár tartalmának megőrzésére. Pontosan erre szolgál a session vagy munkamenet. Megmutatjuk,
- hogyan használjuk a sessionöket
- hogyan kerüljük el a névütközéseket
- hogyan állítsuk be a lejárati időt
Sessionök használatakor minden felhasználó egyedi azonosítót kap, az úgynevezett session ID-t, amelyet cookie-ban továbbítanak. Ez kulcsként szolgál a session adatokhoz. Ellentétben a cookie-kkal, amelyek a böngésző oldalán tárolódnak, a session adatok a szerver oldalán tárolódnak.
A sessiont a konfigurációban állítjuk be, különösen fontos a lejárati idő megválasztása.
A session kezeléséért a Nette\Http\Session objektum
felelős, amelyhez úgy juthat hozzá, hogy dependency injection segítségével átadja
magának. A presenterekben elég csak a $session = $this->getSession()
metódust meghívni.
Session indítása
A Nette alapértelmezés szerint automatikusan elindítja a sessiont abban a pillanatban, amikor elkezdünk olvasni belőle
vagy adatokat írni bele. Manuálisan a session a $session->start()
segítségével indítható el.
A PHP a session indításakor HTTP fejléceket küld, amelyek befolyásolják a gyorsítótárazást, lásd session_cache_limiter, és adott esetben a session ID-t tartalmazó cookie-t is. Ezért mindig el kell indítani a sessiont még azelőtt, hogy bármilyen kimenetet küldenénk a böngészőbe, különben kivétel váltódik ki. Ha tehát tudja, hogy az oldal megjelenítése során sessiont fog használni, indítsa el manuálisan előtte, például a presenterben.
Fejlesztői módban a Tracy indítja el a sessiont, mert azt használja az átirányítási és AJAX kérések sávjainak megjelenítésére a Tracy Barban.
Szekciók
Tiszta PHP-ban a session adattárolója egy tömbként valósul meg, amely a $_SESSION
globális változón
keresztül érhető el. A probléma az, hogy az alkalmazások általában számos egymástól független részből állnak, és
ha mindegyiknek csak egy tömb áll rendelkezésére, előbb-utóbb névütközés következik be.
A Nette Framework ezt a problémát úgy oldja meg, hogy az egész teret szekciókra ( Nette\Http\SessionSection objektumokra) osztja. Minden egység ezután saját, egyedi nevű szekciót használ, és így már nem fordulhat elő ütközés.
A szekciót a sessionből kapjuk meg:
$section = $session->getSection('unikatni nazev');
A presenterben elég a getSession()
-t használni paraméterrel:
// $this je Presenter
$section = $this->getSession('unikatni nazev');
A szekció létezését a $session->hasSection('unikatni nazev')
metódussal ellenőrizhetjük.
Magával a szekcióval ezután nagyon egyszerűen dolgozhatunk a set()
, get()
és
remove()
metódusokkal:
// zápis proměnné
$section->set('userName', 'franta');
// čtení proměnné, vrátí null pokud neexistuje
echo $section->get('userName');
// zrušení proměnné
$section->remove('userName');
Az összes változó megszerzéséhez a szekcióból használhatjuk a foreach
ciklust:
foreach ($section as $key => $val) {
echo "$key = $val";
}
Lejárati idő beállítása
Az egyes szekciókhoz vagy akár egyes változókhoz is beállítható lejárati idő. Így például hagyhatjuk, hogy a felhasználó bejelentkezése 20 perc múlva lejárjon, miközben továbbra is megjegyezzük a kosár tartalmát.
// sekce vyexpiruje po 20 minutách
$section->setExpiration('20 minutes');
Az egyes változók lejárati idejének beállítására a set()
metódus harmadik paramétere szolgál:
// proměnná 'flash' vyexpiruje už po 30 sekundách
$section->set('flash', $message, '30 seconds');
Ne felejtse el, hogy az egész session lejárati ideje (lásd session konfiguráció) meg kell hogy egyezzen vagy magasabb legyen, mint az egyes szekciókhoz vagy változókhoz beállított idő.
A korábban beállított lejárati idő törlését a removeExpiration()
metódussal érhetjük el. Az egész
szekció azonnali törlését a remove()
metódus biztosítja.
$onStart, $onBeforeWrite események
A Nette\Http\Session
objektumnak vannak $onStart és
$onBeforeWrite eseményei, így hozzáadhat callbackeket, amelyek a session indítása után vagy a lemezre írása és az azt
követő befejezése előtt hívódnak meg.
$session->onBeforeWrite[] = function () {
// zapíšeme data do session
$this->section->set('basket', $this->basket);
};
Session kezelés
A Nette\Http\Session
osztály metódusainak áttekintése a session kezeléséhez:
start(): void
Elindítja a sessiont.
isStarted(): bool
El van indítva a session?
close(): void
Befejezi a sessiont. A session automatikusan befejeződik a szkript futásának végén.
destroy(): void
Befejezi és törli a sessiont.
exists(): bool
Tartalmaz a HTTP kérés cookie-t session ID-vel?
regenerateId(): void
Új, véletlenszerű session ID-t generál. Az adatok megmaradnak.
getId(): string
Visszaadja a session ID-t.
Konfiguráció
A sessiont a konfigurációban állítjuk be. Ha olyan alkalmazást ír, amely nem használ DI konténert, ezek a metódusok szolgálnak a konfigurációhoz. Ezeket még a session elindítása előtt kell meghívni.
setName (string $name): static
Beállítja annak a cookie-nak a nevét, amelyben a session ID-t továbbítják. A standard név PHPSESSID
.
Hasznos abban az esetben, ha egy webhelyen belül több különböző alkalmazást üzemeltet.
getName(): string
Visszaadja annak a cookie-nak a nevét, amelyben a session ID-t továbbítják.
setOptions (array $options): static
Konfigurálja a sessiont. Beállíthatók az összes PHP session direktíva (camelCase formátumban, pl.
session.save_path
helyett savePath
-t írunk) és a readAndClose is.
setExpiration (?string $time): static
Beállítja az inaktivitási időt, amely után a session lejár.
setCookieParameters (string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null): static
Cookie paraméterek beállítása. A paraméterek alapértelmezett értékeit megváltoztathatja a konfigurációban.
setSavePath (string $path): static
Beállítja a könyvtárat, ahová a session fájlok mentésre kerülnek.
setHandler (\SessionHandlerInterface $handler): static
Saját handler beállítása, lásd PHP dokumentáció.
Biztonság mindenekelőtt
A szerver feltételezi, hogy ugyanazzal a felhasználóval kommunikál, amíg a kéréseket ugyanaz a session ID kíséri. A biztonsági mechanizmusok feladata annak biztosítása, hogy ez valóban így legyen, és ne lehessen az azonosítót ellopni vagy meghamisítani.
A Nette Framework ezért helyesen konfigurálja a PHP direktívákat, hogy a session ID-t csak cookie-ban továbbítsa, JavaScript számára hozzáférhetetlenné tegye, és az URL-ben lévő esetleges azonosítókat figyelmen kívül hagyja. Ezenkívül kritikus pillanatokban, mint például a felhasználó bejelentkezésekor, új session ID-t generál.
A PHP konfigurálásához az ini_set függvényt használják, amelyet sajnos néhány hosting szolgáltató letilt. Ha ez az Ön szolgáltatójának esete is, próbáljon meg velük megegyezni, hogy engedélyezzék a függvényt, vagy legalább konfigurálják a szervert.