Ověření platnosti autentizace při každém přístupu

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
DocX
Člen | 154
+
0
-

Ahoj,

řeším problém s autentizací, kdy potřebuji, aby se při každém požadavku na stránku znovu ověřilo, zda uživatel může být přihlášen (např. pokud mezitím administrátor uživatele nezablokoval, nesmazal, nesnížil práva apod.) a zároveň tím pokaždé aktualizovat uživatelská data. Nejprve jsem chtěl extendnout třídu User z Nette a upravit implementaci funkce isAuthenticated, při níž by se vlastně volalo vnitřně authenticate. Něco ve smyslu:

<?php

class MyUser extends User
{
	public function isAuthenticated()
	{
		$identity = $this->getIdentity();
		try
		{
			$this->authenticate($identity->username, $identity->password);
		}
		catch(AuthenticationException $e)
		{
			return FALSE;
		}

		return parent::isAuthenticated();
	}
}

?>

Jenže problém je v tom, že User::isAuthenticated je deklarovaná jako final. Samozřejmě mohl bych vzít soubor se třídou User, zkopírovat, přejmenovat třídu na MyUser a upravit. Ale proč?

Případně máte nějaký jiný nápad jak tento problém řešit?

Díky :)

vlki
Člen | 218
+
0
-

No, nenapadá mne lepší přístup, ale možná jen jiný druh provedení. Přidat tam handler.

Patch s handlerem.

--- a/Nette/Web/User.php
+++ b/Nette/Web/User.php
@@ -59,6 +59,9 @@ class User extends /*Nette\*/Object implements IUser

 	/** @var array of function(User $sender); Occurs when the user is successfully authenticated */
 	public $onAuthenticated;
+
+	/** @var array of function(User $sender); Occurs when is checked if the user is authenticated */
+	public $onAuthenticationCheck;

 	/** @var array of function(User $sender); Occurs when the user is logged off */
 	public $onSignedOut;
@@ -136,6 +139,7 @@ class User extends /*Nette\*/Object implements IUser
 	 */
 	final public function isAuthenticated()
 	{
+		$this->onAuthenticationCheck($this);
 		$session = $this->getSessionNamespace(FALSE);
 		return $session && $session->authenticated;
 	}

Pak by sis jen před zavoláním metody isAuthenticated zaregistroval nějaké callbacky. Třeba na model, který teď implementuje IAuthenticator. Tam by sis už mohl dělat prakticky cokoli:)

	$user = Environment::getUser();
	$userAuthenticator = new UserAuthenticator;
	$user->onAuthenticationCheck[] = array($userAuthenticator, 'check');
	if (!$user->isAuthenticated())
		$this->redirect('pryc');
class UserAuthenticator extends Object implements IAuthenticator
{
	...

	public function check(User $user)
	{
		$identity = $user->getIdentity();
		try {
			$this->authenticate($identity->username, $identity->password);
		} catch(AuthenticationException $e) {
			$user->signOut();
		}
	}

	...
}
DocX
Člen | 154
+
0
-

vlki napsal(a):

No, nenapadá mne lepší přístup, ale možná jen jiný druh provedení. Přidat tam handler.

Jo to je taky hezký :). Je to ale spíš už na začlenění přímo do Nette. Já to nepotřebuji takto univerzální, takže jsem metodu User::isAuthenticated() udělal nefinální a pak ji přepsal ve vlastní odvozené třídě.

Šlo mi spíše o to, proč tam to final vůbec je, pořád mi to nedává moc smysl :)

PS: to $user->signOut(); v ošetření vyjímky autentizace není potřeba, protože to dělá na začátku přímo funkce User::authenticate() ;)

Editoval DocX (18. 8. 2009 12:52)