Nette Documentation Preview

syntax
Sessionök
*********

<div class=perex>

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

</div>

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 |configuration#Session] állítjuk be, különösen fontos a lejárati idő megválasztása.

A session kezeléséért a [api:Nette\Http\Session] objektum felelős, amelyhez úgy juthat hozzá, hogy [dependency injection |dependency-injection:passing-dependencies] 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 |@home#Telepítés]


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 [php: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 ( [api: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:

```php
$section = $session->getSection('unikatni nazev');
```

A presenterben elég a `getSession()`-t használni paraméterrel:

```php
// $this egy 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:

```php
// változó írása
$section->set('userName', 'franta');

// változó olvasása, null-t ad vissza, ha nem létezik
echo $section->get('userName');

// változó törlése
$section->remove('userName');
```

Az összes változó megszerzéséhez a szekcióból használhatjuk a `foreach` ciklust:

```php
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.

```php
// a szekció 20 perc múlva lejár
$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:

```php
// a 'flash' változó már 30 másodperc múlva lejár
$section->set('flash', $message, '30 seconds');
```

.[note]
Ne felejtse el, hogy az egész session lejárati ideje (lásd [session konfiguráció |configuration#Session]) 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 |nette:glossary#Eventek események], í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.

```php
$session->onBeforeWrite[] = function () {
	// adatokat írunk a sessionbe
	$this->section->set('basket', $this->basket);
};
```


Session kezelés
===============

A `Nette\Http\Session` osztály metódusainak áttekintése a session kezeléséhez:

<div class=wiki-methods-brief>


start(): void .[method]
-----------------------
Elindítja a sessiont.


isStarted(): bool .[method]
---------------------------
El van indítva a session?


close(): void .[method]
-----------------------
Befejezi a sessiont. A session automatikusan befejeződik a szkript futásának végén.


destroy(): void .[method]
-------------------------
Befejezi és törli a sessiont.


exists(): bool .[method]
------------------------
Tartalmaz a HTTP kérés cookie-t session ID-vel?


regenerateId(): void .[method]
------------------------------
Új, véletlenszerű session ID-t generál. Az adatok megmaradnak.


getId(): string .[method]
-------------------------
Visszaadja a session ID-t.

</div>


Konfiguráció
------------

A sessiont a [konfigurációban |configuration#Session] á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.

<div class=wiki-methods-brief>


setName(string $name): static .[method]
---------------------------------------
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 .[method]
---------------------------
Visszaadja annak a cookie-nak a nevét, amelyben a session ID-t továbbítják.


setOptions(array $options): static .[method]
--------------------------------------------
Konfigurálja a sessiont. Beállíthatók az összes PHP [session direktíva |https://www.php.net/manual/en/session.configuration.php] (camelCase formátumban, pl. `session.save_path` helyett `savePath`-t írunk) és a [readAndClose |https://www.php.net/manual/en/function.session-start.php#refsect1-function.session-start-parameters] is.


setExpiration(?string $time): static .[method]
----------------------------------------------
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 .[method]
---------------------------------------------------------------------------------------------------------------------
Cookie paraméterek beállítása. A paraméterek alapértelmezett értékeit megváltoztathatja a [konfigurációban |configuration#Session cookie].


setSavePath(string $path): static .[method]
-------------------------------------------
Beállítja a könyvtárat, ahová a session fájlok mentésre kerülnek.


setHandler(\SessionHandlerInterface $handler): static .[method]
---------------------------------------------------------------
Saját handler beállítása, lásd [PHP dokumentáció|https://www.php.net/manual/en/class.sessionhandlerinterface.php].

</div>


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.

.[note]
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.

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 egy 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:

// változó írása
$section->set('userName', 'franta');

// változó olvasása, null-t ad vissza, ha nem létezik
echo $section->get('userName');

// változó törlése
$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.

// a szekció 20 perc múlva lejár
$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:

// a 'flash' változó már 30 másodperc múlva lejár
$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 () {
	// adatokat írunk a sessionbe
	$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.