2 a více druhů přihlášení na webu

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

Zdravím, problém je následující. Tvořím web, kde bych chtěl mít jednu autentifikaci do admina a druhou pro přihlášení uživatele na webu. Mám vytvořeny 2 tabulky. Users(uživatelé admina) a WebUsers(uživatele webu). Nevím ale, jak toto rozdělit i v presenteru. Nevěděl by někdo jak tohle vyřešit.

Tharos
Člen | 1030
+
0
-

Nejpraktičtější je používat dva různé session jmenné prostory (pro vlastní přihlášení a i další session data).

$user = Nette\Environment::getUser();
$user->setNamespace('WebUser'); // například, osobně bych použil namespace jen pro správce webu
// zda bude pravděpodobně následovat autentizace a další aktivity závislé na konkrétním uživatelském účtu

Editoval Tharos (19. 2. 2011 23:35)

gavec
Člen | 68
+
0
-

oukej, tak namespace jsem nastavil. Ted Jak nastavit kontrolu prihlasovacich udaju z jine tabulky?

Tharos
Člen | 1030
+
0
-

Každému z těch typů uživatelů můžeš nastavit vlastní autentizační handler. Ten mohou představovat dvě úplně nezávislé modelové třídy pracující s úplně jinými databázovými tabulkami.

newPOPE
Člen | 648
+
0
-

zaujimavy problem :-).

celkom sa mi pozdava ze by sa na zaklade nastavenia ->setNamespace('admin') volala v Authenicatore ->authenticateAdmin(...) ale tak to nefunguje… (mozno RFC :-D)

Editoval newPOPE (20. 2. 2011 1:16)

Tharos
Člen | 1030
+
0
-

newPOPE: To ale vůbec není zapotřebí, autentizace těch dvou typů uživatelů může být úplně nezávislá. A díky těm jmenným prostorům v session mohou být i úplně nezávislá i vícenásobná přihlášení z jednoho prohlížeče (tj. z jednoho prohlížeče se lze nezávisle přihlásit jako registrovaný uživatel ve frontendu i jako admin v backendu).

newPOPE
Člen | 648
+
0
-

Tharos napsal(a):

ja som mal na mysli ten vyber z tabulky, nenapada ma sposob ako toho v authenticate dosiahnut (v pripade ze nechcem kontrolovat obidve)

moj bezny postup

<?php
	$user = Nette\Environment::getUser();
	$user->setNamespace('WebUser'); //ked je to potrebne...
	$user->login($name, $pass);
?>

a v authenticate overim a vratim identitu, vsetko v poriadku ale ako rozlisim (mozno nieco ako Env...->getNamespace()) oproti ktoremu namespacu(tabulke etc…) chcem overovat.

PS: je pokrocila hodina tak sa mi nechce skusat, radsej podiskutujem ;-)

gavec
Člen | 68
+
0
-

No vyřešil jsem to tak, že se metoda authenticate v modelu „UsersMode“ provede jen v případě, že není nastaven namespace na ‚admin‘ (if($namespace = $user->getNamespace(‚admin‘)){…}). V případě, že nastaven není veme to metodu authenticate z dalšího modelu. Je tohle dobré řešení???

Tharos
Člen | 1030
+
0
-

newPOPE:

$webUserAuthHandler = new WebUserAuthHandler();
// $webUserAuthHandler instanceof Nette\Security\IAuthenticator === true

$user = Nette\Environment::getUser();
$user->setNamespace('WebUser'); //ked je to potrebne...
$user->setAuthenticationHandler($webUserAuthHandler);
$user->login($name, $pass);

Editoval Tharos (20. 2. 2011 2:01)

Tharos
Člen | 1030
+
0
-

gavec: No, asi to funguje (a účel světí prostředky), ale žádný skvost to není ;). Ono se v zásadě jedná dokonce o porušení MVP. UsersModel by měl jen „tupě“ poskytovat službu autentizace, neměl by se vůbec starat o nějaký jmenný prostor session (to je zde doména P vrstvy). Model vůbec nemusí vědět, že se v P vrstvě pracuje s nějakými sessions.

Proč pro toho admina prostě nevytvoříš naznačeným způsobem v modelu vlastní autentizační třídu? To je přece mnohem elegantnější.

Chbox
Člen | 125
+
0
-

…mě by spíš zajímalo, co má být účelem rozdělit uživatele na 2 tabulky a proč dělat 2 authentizace?

jasir
Člen | 746
+
0
-

admin presenter:

<?php
public function getUser() {
	$user = parent::getUser();
	return $user->setNamespace('Admin')->setAuthenticationHandler(new AdminAuthenticator);
}
?>

frontend presenter:

<?php
public function getUser() {
	$user = parent::getUser();
	return $user->setAuthenticationHandler(new FrontendAuthenticator);
}
?>

Editoval jasir (20. 2. 2011 2:18)

jasir
Člen | 746
+
0
-

Chbox napsal(a):

…mě by spíš zajímalo, co má být účelem rozdělit uživatele na 2 tabulky a proč dělat 2 authentizace?

Podle mě je to správný přítup mít úplně oddělené uživatele administrace a frontendu.

gavec
Člen | 68
+
0
-

Takže když mám a admin presenteru tento startup:

protected function startup()
	{
		// user authentication
		$user = NEnvironment::getUser()->setNamespace('admin');
		if (!$this->getUser()->isLoggedIn()) {

			if ($this->getUser()->getLogoutReason() === NUser::INACTIVITY) {
				$this->flashMessage('You have been logged out due to 	inactivity. Please login again.');
			}
			$backlink = $this->getApplication()->storeRequest();
			$this->redirect('Login:default', array('backlink' => $backlink));
		}

		parent::startup();
	}

je pořeba před něj vložit fuknci getUser:

public function getUser() {
        $user = parent::getUser();
        return $user->setNamespace('Admin')->setAuthenticationHandler(new AdminAuthenticator);
}

A potom v daném modelu vytvořit třídu AdminAuthenticator?

Např když UsersModel vypadá takto:

<?php

class UsersModel extends NObject implements IAuthenticator
{
	public function authenticate(array $credentials)
	{
		$username = $credentials[self::USERNAME];
		$password = $credentials[self::PASSWORD];
     	$user = NEnvironment::getUser();
		if($namespace = $user->getNamespace('admin')){

		$row = dibi::fetch('SELECT * FROM users WHERE login=%s', $username);

		if (!$row) {
			throw new NAuthenticationException("User '$username' not found.", self::IDENTITY_NOT_FOUND);
		}

		if ($row->password !== $password) {
			throw new NAuthenticationException("Invalid password.", self::INVALID_CREDENTIAL);
		}

		unset($row->password);
		return new NIdentity($row->id, $row->role, $row);
		}else{
			return true;
		}
	}


	private $table = 'users';


	private $connection;


	public static function initialize()
	{
		dibi::connect(NEnvironment::getConfig('database'));
	}



	public function __construct()
	{
		$this->connection = dibi::getConnection();
	}



	public function findAll()
	{
		return $this->connection->select('*')->from($this->table);
	}



	public function find($id)
	{
		return $this->connection->select('*')->from($this->table)->where('id=%i', $id);
	}



	public function update($id, array $data)
	{
		return $this->connection->update($this->table, $data)->where('id=%i', $id)->execute();
	}



	public function insert(array $data)
	{
		return $this->connection->insert($this->table, $data)->execute(dibi::IDENTIFIER);
	}



	public function delete($id)
	{
		return $this->connection->delete($this->table)->where('id=%i', $id)->execute();
	}
}

Jak je ho potřeba upravit?

newPOPE
Člen | 648
+
0
-

Tharos napsal(a):

Vdaka, zase som o nieco mudresjsi ;-)

gavec
Člen | 68
+
0
-

Tak už jsem to pochopil. Díky moc