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.

Telepítés és követelmények

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.

verzió: 4.0