Protokol HTTP je bezestavový. Což znamená, že každý dotaz na server je nezávislý a že si server nepamatuje stav komunikace. Takto by však nebylo možné implementovat žádnou jen trošku složitější aplikaci, např. internetový obchod, který si potřebuje uchovávat obsah nákupního košíku. Proto byl protokol HTTP rozšířen o tzv. HTTP cookies, krátké textové řetězce, které umožňují informace o stavu uchovávat.
Chcete se naučit o Nette víc?
Akademie Root.cz školení Vývoj webových aplikací v Nette Framework. Kurz je určen všem programátorům v PHP, kteří se chtějí naučit tvořit webové aplikace rychle a kvalitně, bez bezpečnostních děr. Jako aplikační rámec slouží Nette Framework. Školí sám autor Nette – David Grudl. Máte zájem o jiné školení? Napište nám!
Jelikož tyto řetězce jsou skutečně krátké a ukládají se na straně prohlížeče, nemusí být vždy možné nebo vhodné do nich celý stav zapisovat. Řešením jsou tzv. sessions (česky relace, sezení). Princip je ten, že informace o stavu se uchovávají na straně serveru, kde jsou dostupné pod jedinečným identifikátorem zvaným Session ID a ten jediný stačí uložit do HTTP cookie.
Bezpečnost především
Server tedy předpokládá, že komunikuje stále s tímtéž uživatelem, dokud požadavky doprovází stejné Session ID. Úkolem bezpečnostních mechanismů je zajistit, aby tomu tak doopravdy bylo.
Když se někdy v devadesátých letech začalo diskutovat o bezpečnosti webových aplikací, vznikl mýtus, že cookies jsou samy o sobě nebezpečné a rádobyodborníci nabádali veřejnost, aby si je vypínala. Což samozřejmě ochromilo celou řadu webových aplikací. Aby mohly fungovat i bez cookies, začalo se Session ID přenášet také v URL. Což teprve zavdalo vzniku těch největších bezpečnostních děr. Obrácená kauzalita.
Dnes už je situace zcela jiná. Uživatelé si cookies nevypínají a bezpečnost aplikací má vysokou prioritu. Velmi důležité je tedy nakonfigurovat server tak, aby Session ID přenášel pouze v cookie, znepřístupnil jej JavaScriptu a případné identifikátory v URL ignoroval.
Nette Framework na scénu!
Jak už zaznělo v předcházejících dílech seriálu, Nette Framework klade velký důraz na bezpečnost aplikací. Připomeňme třeba šablonovací systém, který má ambici zcela eliminovat Cross Site Scripting. Nepřekvapí proto, že framework se snaží co nejlépe zabezpečit i sessions. Dělá to zcela transparentně, aniž byste museli cokoliv manuálně nastavovat.
Nette Framework tedy sám správně nakonfiguruje PHP direktivy*), kontroluje neměnost vybraných HTTP hlaviček zasílaných prohlížečem, v kritických okamžicích, jako je třeba přihlášení uživatele, vygeneruje Sesssion ID nové atd.
*) pro konfiguraci PHP se používá funkce ini_set, kterou bohužel některé hostingy nepovolují. Pokud je to případ i vašeho hostéra, pokuste se s ním domluvit, aby vám funkci povolil nebo alespoň server nakonfiguroval. Nevyhoví-li, vůbec neváhejte a hostéra změňte. Ušetříte si tak spoustu problémů.
Přístup k sessions obstarává objekt třídy NetteWebSession
. Jelikož jde o singleton, nevytváříme jeho instanci přímo, ale vrátí ji metoda Environment::getSession()
. Poté můžeme dokončit konfiguraci. Například takto lze nastavit dobu expirace, zvolit adresář pro soubory se stavem relací a upřesnit parametry cookie:
require 'Nette/loader.php';
$session = Environment::getSession();
// nastavení expirace: relace vyprší po 3 hodinách neaktivity
$session->setExpiration(3 * 60 * 60);
// nastavení cesty, kam se mají ukládat soubory na serveru
$session->setSavePath(dirname(__FILE__) . '/sessions/');
// nastavení parametrů cookie: bude dostupné jen na doméně forum.example.com
$session->setCookieParams('/', 'forum.example.com');
Konfigurace musí být provedena dříve, než se začnou session data používat. V aplikacích je nejvhodnější ji umístit do bootstrap.php
.
Ještě se zastavím u volby doby expirace. Výchozí hodnota „do zavření okna prohlížeče“ nemusí být vždy optimální. Metoda setExpiration()
jako parametr akceptuje relativní čas v sekundách nebo UNIX timestamp, v aktuální verzi frameworku je možné použít i velmi srozumitelný textový zápis:
// relace vyprší po 14 dnech neaktivity
$session->setExpiration('+ 14 days');
Session není potřeba startovat nebo uzavírat, tohle provádí framework automaticky.
Jmenné prostory
V čistém PHP je datové úložiště session realizováno jako pole dostupné přes globální proměnnou $_SESSION
. Problém je v tom, že aplikace se běžně skládá z celé řady vzájemně nezávislých částí a pokud všechny mají k dispozici jen jedno pole, dříve nebo později dojde ke kolizi názvů.
Nette Framework problém řeší tak, že celý prostor rozděluje na jmenné prostory. Každá část programu pak používá svůj jmenný prostor (s unikátním názvem) a k žádné kolizi již dojít nemůže. Se jmenným prostorem se pracuje podobně, jako by šlo o objekt:
// získáme přístup do jmenného prostoru 'myCounter'
$namespace = $session->getNamespace('myCounter');
// nastavíme proměnnou
$namespace->a = 'apple';
// lze použít i syntax: $namespace['a'] = 'apple';
// přečteme proměnnou
echo $namespace->a;
// zrušíme proměnnou
unset($namespace->a);
Nette nabízí zkratku, místo Environment::getSession()->getNamespace('prostor')
lze psát Environment::getSession('prostor')
.
Velmi užitečnou vlastností je možnost nastavit vlastní expiraci pro jednotlivé jmenné prostory nebo dokonce pro jednotlivé proměnné:
// jmenný prostor vyexpiruje po 60 sekundách
$namespace->setExpiration(60);
// a proměnná $namespace->a vyexpiruje už po 10 sekundách
$namespace->setExpiration(10, 'a');
Opět je možné kromě relativního času v sekundách použít UNIX timestamp nebo textový zápis. Zajímavostí je hodnota 0
, který nastaví expiraci na okamžik, kdy uživatel zavře okno prohlížeče:
// proměnná $namespace->password vyexpiruje, jakmile uživatel zavře okno prohlížeče
$namespace->setExpiration(0, 'password');
Nezapomeňte, že doba expirace celé session musí být stejná nebo větší, než doba nastavená u jednotlivých prostorů či proměnných.
Pokračování příště
Příště se podíváme na přihlašování uživatelů.
Autor článku je vývojář na volné noze, specializuje se na návrh a programování moderních webových aplikací. Vyvíjí open-source knihovny Texy, dibi a Nette Framework a pravidelně pořádá školení pro tvůrce webových aplikací, které od podzimu 2009 nabídne kurz vývoje AJAXových aplikací.
Přehled komentářů