Nette\Web\User
Zajišťuje přihlašování a odhlašování uživatelů, popisuje jejich identitu a ověřuje práva na základě rolí.
Autentizace (přihlášení)
Přihlášení a odhlášení uživatele:
$user = new User;
// přihlášení
$user->authenticate($userName, $password); // předáme přihlašovací jméno a heslo
// ověření, zda je uživatel přihlášen
if ($user->isAuthenticated()) ...
// jednoduché odhlášení
$user->signOut();
Přihlašování vyžaduje u uživatele povolené cookies; jiná metoda přihlašování není bezpečná!
Oveření uživatelského jména a hesla provádí autentizační handler,
což je objekt implementující rozhraní
Nette\Security\IAuthenticator. Jeho triviální implementací je
třída Nette\Security\SimpleAuthenticator, která dostane
v konstruktoru seznam uživatelů a hesel jakožto asociativní pole. Úkolem
handleru je v metodě authenticate(array $credentials) ověřit,
zda uživatelské jméno a heslo odpovídá a v případě úspěchu vrátit
tzv. identitu. Neúspěch indikuje vyhozením výjimky
Nette\Security\AuthenticationException s popisem důvodu. Lze
využít i připravené konstanty
IAuthenticator::IDENTITY_NOT_FOUND nebo
IAuthenticator::INVALID_CREDENTIAL.
$authenticator = new SimpleAuthenticator(array(
'john' => 'IJ^%4dfh54*',
'kathy' => '12345', // Kathy, this is very weak password!
));
$user->setAuthenticationHandler($authenticator);
Automatické odhlášení
Ve výchozím nastavení je uživatel odhlášen v okamžiku, kdy zavře
okno prohlížeče. Chování lze změnit metodou setExpiration().
První parametr určuje čas v sekundách, za který bude uživatel
v případě neaktivity odhlášen. Druhý parametr říká, zda uživatele
odhlásit v okamžiku zavření okna prohlížeče. Třetí parametr stanoví,
zda při odhlášení smazat identitu.
// uživateli zůstane při odhlášení identita
$user->signOut(); // nebo $user->signOut(FALSE);
// uživatelova identita bude smazána - hodí se u případů,
// kdy je počítač sdílený a chci se odhlásit
// a nezanechat po sobě žádné osobní údaje
$user->signOut(TRUE);
// odhlásit uživatele po 14 dnech neaktivity
$user->setExpiration(1209600, FALSE);
// odhlásit uživatele po jednom dni neaktivity, nebo až zavře prohlížeč
$user->setExpiration(86400, TRUE);
// odhlásit uživatele až zavře prohlížeč (bez časového limitu)
$user->setExpiration(0, TRUE);
// automatické odhlášení uživatele po 15 minutách neaktivity
// nebo zavření prohlížeče s odstraněním identity
$user->setExpiration(15*60, TRUE, TRUE);
Expirace Nette\Web\Session musí být nastavena na stejnou nebo vyšší hodnotu, jakou má expirace přihlášení
Identita
Identita je objekt implementující rozhraní
Nette\Security\IIdentity. Nette\Web\User jej udržuje v session.
Jeho výchozí implementace Nette\Security\Identity udržuje
informaci o jméně, rolích a dalších uživatelských datech.
Ačkoliv má uživatel identitu, nemusí být
přihlášený! Identita se sice obvykle získá při přihlášení,
ale i když vás systém po nějaké době odhlásí
($user->signOut()), stále si ji pamatuje (jméno, obsah
košíku na eshopu, …).
Pokud se to hodí, můžeme při odhlášení identitu vymazat:
$user->signOut(TRUE).
Autorizace
Autorizace = zjištění, zda má uživatel právo to či ono udělat. Rozhoduje se na základě rolí a toho, zda je uživatel přihlášen. V nejjednodušších případech si vystačíme právě s indikátorem přihlášení:
if ($user->isAuthenticated()) ..
Silnější mechanismus je rozhodování na základě rolí:
- každý uživatel může mít v jednu chvíli přiřazeno více rolí
- nepřihlášený uživatel má automaticky roli
$user->guestRole(výchozí hodnota'guest') - autentizovaný (tj. přihlášený) uživatel bez identity
má automaticky roli
$user->authenticatedRole(výchozí hodnota'authenticated') - autentizovaný uživatel s identitou (
$user->getIdentity()) vychozí roli nezíská, o role se stará$user->getIdentity()->getRoles()
if ($user->isInRole('editor')) ..
S tím si u většiny Běžných Aplikací™ vystačíte.
Nejsilnější mechanismus poskytuje autorizační handler
($user->authorizationHandler), tj. objekt implementující
rozhraní Nette\Security\IAuthorizator s metodou
isAllowed(). Jeho implementací je právě třída Nette\Security\Permission,
do hry tak kromě rolí vstupují i parametery resource & privilege.
if ($user->isAllowed($resource, $privilege)) ..
Protože uživatel může mít více rolí, povolení dostane, pokud alespoň jedna role má povolení. Oba parametry jsou volitelné, výchozí hodnota nese význam všechny. Takže pokud např. parametr $privilege nevyužijeme, můžeme ho vynechat.
Ještě upozornění: pokud uživateli po odhlášení zůstane identita, tak
i včetně všech rolí – získatelných přes
$user->getIdentity()->getRoles(). Nicméně metoda
$user->getRoles() stav přihlášení zohledňuje. Stejně tak
i dotazy isInRole() a isAllowed() – proto je není nutné kombinovat
s dotazem isAuthenticated().
Odkud se handlery berou?
Globální úložiště pro služby (services) poskytuje Nette\Environment::getServiceLocator(), zkratkou pro získání objektu User je Environment::getUser(). Objekt Nette\Web\User má settery pro autorizační a autentizační handlery, ale aby to celé pracovalo hezky líně (tj. objekty se vytvářejí, až když jsou skutečně potřeba), pokouší se Nette\Web\User získat handlery opět přes metodu Nette\Environment::getService(), kde je identifikátorem název interface.
Stačí tedy nastavit:
Environment::getServiceLocator()->addService($authenHandler, 'Nette\Security\IAuthenticator');
Environment::getServiceLocator()->addService($authorHandler, 'Nette\Security\IAuthorizator');
// kde handler je buď hotový objekt (pak to ale není lazy), jméno třídy nebo callback na továrnu
Službu lze nastavit i skrze config.ini:
service.Nette-Security-IAuthenticator = MyAuthenticator
Více aplikací v jednom prostoru
V rámci jedné aplikace (serveru, session) může fungovat více aplikací, s tím, že si každá spravuje přihlašování samostatně. Stačí každé nastavit vlastní jmenný prostor:
$user->setNamespace('forum');
Viz také:
