2 a více druhů přihlášení na webu
- gavec
- Člen | 68
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
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)
- Tharos
- Člen | 1030
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.
- Tharos
- Člen | 1030
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
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
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
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
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ší.
- jasir
- Člen | 746
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)
- gavec
- Člen | 68
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?