EN | CS | Přihlásit | Registrovat

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->login($userName, $password); // předáme přihlašovací jméno a heslo

// ověření, zda je uživatel přihlášen
if ($user->isLoggedIn()) ...

// jednoduché odhlášení
$user->logout();

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ě login(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->logout(); // nebo $user->logout(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->logout(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);

Pokud při ověřování autentizace uživatele zjistíme, že není přihlášen, můžeme jít ještě dál a zjistit příčinu odhlášení. Nette umožňuje zjistit metodou getLogoutReason() základní příčiny odhlášení jako zavření okna prohlížeče, neaktivita nebo manuální odhlášení uživatele. Můžeme tak například pomocí flash zpráviček dát uživateli vědět o příčině jeho odhlášení.

Z jakého důvodu byl uživatel odhlášen prozradí metoda $user->getLogoutReason(). Pokud vypršel časový limit vrací User::INACTIVITY, pokud uživatel zavřel okno prohlížeče vrací User::BROWSER_CLOSED a pokud byl uživatel odhlášen voláním metody logout() vrací User::MANUAL.

// user authentication
$user = Environment::getUser();
if (!$user->isLoggedIn()) {
if ($user->getLogoutReason() === User::INACTIVITY) {
$this->flashMessage('You have been logged out due to inactivity. Please login again.');
}

// stejným způsobem zjistíme User::BROWSER_CLOSED a User::MANUAL
}

Dále je možno využít událostí onLoggedIn a onLoggedOut například pro jednoduchého přidání callbacku pro logování autorizačních aktivit na webu. Událost onLoggedIn je volána po úspěšném přihlášení. Událost onLoggedOut je zpracována po odhlášení uživatele, ať už se odhlásil sám nebo z důvodu neaktivity či zavření prohlížeče.

$user->onLoggedIn[] = array($logger, 'loginMethod');
$user->onLoggedOut[] = array($logger, 'logoutMethod');

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 (na uživatelská data si můžeme šáhnout přes Environment::ge­tUser()->getIdentity()->promena).

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->logout()), 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->logout(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->isLoggedIn()) ..

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\Per­mission, 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 isLoggedIn().

Odkud se handlery berou?

Globální úložiště pro služby (services) poskytuje Nette\Environ­ment::getServi­ceLocator(), zkratkou pro získání objektu User je Environment::ge­tUser(). 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\Environ­ment::getServi­ce(), 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é:


Login to submit a comment