Multi přihlašování do dvou modulů
- Nika
- Člen | 4
Zdravím lidi,
jsem začátečník, učím se Nette. Procházel jsem fórum a téma multi
přihlašování se tu řeší dost často.
Snažil jsem se to vyřešit sám podle toho co jsem našel tady na fóru a že
toho bylo dost.
Zkoušel jsem to podle tohoto: http://www.egoblog.cz/…nimi-moduly/ + co jsem našel tady
na foru.
Nakonec jsem se do toho totálně zamotal a nevím jak dál.
Mám jednoduchou dvoumodulovou aplikaci. PublicModule a AdminModule. Do každého modulu bych se potřeboval přihlašovat zvlášť.
Moc bych vás chtěl poprosit, jestli by někdo neměl po ruce nějakou názornou ukázku správného použití multi přihlašování do dvou modulů. Myslím, že bych nebyl jediný, komu by to moc pomohlo do začátku.
Mockrát děkuji.
- Nika
- Člen | 4
Podle toho vlákna jsem to právě zkoušel. Ale docela se ztrácím
v některých pojmech.
Zkusím si to tedy ujasnit.
Budu potřebovat dva Authenticatory, pro každý modul jeden, když mám přihlašovací data v různých tabulkách. V nette sandboxu je v App/model třída UserManager. To je authenticator?
Oba dva si zaregistruju jako služby abych si je mohl injectout do SignPresenteru, kde pomocí
$user = $this->getUser();
$user->setAuthenticator($this->authentificator);
nastavím, který budu používat. Říkám to dobře?
Editoval Nika (24. 6. 2015 11:56)
- h4kuna
- Backer | 740
A co vyprdnout se na IAuthenticator a udělat to takto
Metodě login ve třídě Nette\Secuirty\User můžeš předat Identity a toho využít.
Jde o to že si uděláš službu do ní si injektneš Nette\Security\User a vyrobíš si požadovaný metody třeba:
- logout
- loginPassword
- loginFacebook
- loginModul1
- loginModul2
- private myLogin
A každá metoda jenom jiným způsobem vyrobí itentitu kterou předá do myLogin a ta zavolá $this->user->login($identity);
Editoval h4kuna (24. 6. 2015 12:44)
- Nika
- Člen | 4
Super díky moc. Vypadá, že to funguje.
Nastavení namespace:
$this->user->getStorage()->setNamespace('App\ClientModule');
Stačí to nastavit jen ve funkcích loginModul1, loginModul2 a BasePresenterech?
BasePresenter:
protected function startup()
{
parent::startup();
$user = parent::getUser();
$user->getStorage()->setNamespace('App\AdminModule');
}
Nebo ještě někde dál?
A co s autowired?
Ještě jednou díky moc.
- h4kuna
- Backer | 740
Aha, ty chceš být přihlášen ve dvou modulech a pokaždé s jinou identitou? Neměli by toto řešit práva (Authorizator)? Jedna identita a pak podle oprávnění pustit nebo nepustit do modulu.
Jinak asi ano v metodě si nastavíš namespace a pak v presenteru se přepneš na ten požadovaný.
Autowire? Nerozumím. Jelikož nemá implementaci IAuthenticator tak to nebude injektovat do Nette\Security\User.
- Nika
- Člen | 4
Po pořádném otestování jsem zjistil, že to nefunguje správně.
třída CredentialsAuthenticator:
class CredentialsAuthenticator
{
/** @var Nette\Security\User */
private $user;
/** @var Nette\Database\Context */
private $database;
public function __construct(Nette\Security\User $user, Nette\Database\Context $database)
{
$this->user = $user;
$this->database = $database;
}
public function clientLogin($username, $password)
{
$row = $this->database->table('loginuser')->where('name', $username)->fetch();
if (!$row) {
throw new Nette\Security\AuthenticationException('Nesprávné přihlašovací jméno.');
}
if (!($password == $row['password'])) {
throw new Nette\Security\AuthenticationException('Nesprávné heslo.');
}
$this->user->getStorage()->setNamespace('App\ClientModule');
$this->user->login(new Nette\Security\Identity($row['id'], $row['name']));
}
public function adminLogin($username, $password)
{
$row = $this->database->table('loginadmin')->where('name', $username)->fetch();
if (!$row) {
throw new Nette\Security\AuthenticationException('Nesprávné přihlašovací jméno.');
}
if (!($password == $row['password'])) {
throw new Nette\Security\AuthenticationException('Nesprávné heslo.');
}
$this->user->getStorage()->setNamespace('App\AdminModule');
$this->user->login(new Nette\Security\Identity($row['id'], $row['name']));
}
}
SignPresenter modulu admin: (v druhém modulu vypadá signPresenter podobně):
class SignPresenter extends Nette\Application\UI\Presenter
{
/** @var CredentialsAuthenticator @inject */
public $credentialsAuthenticator;
protected function createComponentSignInForm()
{
$form = new Form;
$form->addText('username', 'Username:')
->setRequired('Please enter your username.');
$form->addPassword('password', 'Password:')
->setRequired('Please enter your password.');
$form->addCheckbox('remember', 'Keep me signed in');
$form->addSubmit('send', 'Sign in');
$form->onSuccess[] = array($this, 'formSucceeded');
return $form;
}
public function formSucceeded($form, $values)
{
if ($values->remember) {
$this->user->setExpiration('14 days', FALSE);
} else {
$this->user->setExpiration('20 minutes', TRUE);
}
try {
$this->credentialsAuthenticator->adminLogin($values->username, $values->password);
$this->flashMessage('Přihlášení proběhlo úspěšně.');
$this->redirect('Homepage:default');
} catch (Nette\Security\AuthenticationException $e) {
$form->addError('Neprávné jméno nebo heslo');
}
}
public function actionOut()
{
$this->getUser()->logout();
$this->flashMessage('You have been signed out.');
$this->redirect('in');
}
}
BasePresenter:
/**
* Base presenter for all application presenters.
*/
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
protected function startup()
{
parent::startup();
$user = parent::getUser();
$user->getStorage()->setNamespace('App\AdminModule');
}
}
Problém je v tom, že se nedokážu odhlásit. Zavolám metodu actionOut() ze SignPresenteru a pak když se vrátím do Homepage:default daného modulu, tak jsem pořád přihlášený.
Editoval Nika (24. 6. 2015 15:12)
- h4kuna
- Backer | 740
A nemělo by tomu logout() předcházet výběr namespace?
<?php
$user = $this->getUser();
$user->getStorage()->setNamespace('App\AdminModule');
$user->logout();
$user->getStorage()->setNamespace('App\ClientModule');
$user->logout();
?>
S nastavováním namespace pro UserStorage jsem nedělal je to ve verzi 2.3 takže jsem zatím neměl tu čest.
EDIT
Nemáš náhodou špatného předka pro SignPresenter?
Editoval h4kuna (25. 6. 2015 7:01)