Uživatel je přihlášen až v action

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

Zdravím, potřebuji v rodičovském presenteru kontrolovat přístup ke zdroji. Ale v metodě startup uživatel ještě není přihlášen (isLoggedIn() vrátí true až v metodě action…, při prvním volání, při kterém dojde k přihlášení) Jak na ověřování, když startup je brzy a do každé action to dávat nechci? Je to API s drahak/restful a basic auth. (je to „na jeden průchod“), kdybych po přihlášení přesměroval, bylo by to v pořádku, ale bez přesměrování?

Nette 2.3.8

premek_k
Člen | 172
+
+3
-

Sám jsem ještě neřešil, ale tuším, že k tomu se overidne checkRequirements, kde se ta kontrola implementuje. Vyzkoušej.

Editoval premek_k (3. 3. 2016 10:56)

ViPEr*CZ*
Člen | 817
+
+1
-

Ehm… https://doc.nette.org/…n/presenters#…
Voláte onen kód isLoggedIn() až za voláním parent::startup(); ????

premek_k
Člen | 172
+
0
-

@ViPEr*CZ* Dík, myslel jsem si, že to musí jít nějak lépe. Předám dál..

Lukáš Kadlec
Člen | 17
+
0
-

ViPErCZ napsal(a):

Ehm… https://doc.nette.org/…n/presenters#…
Voláte onen kód isLoggedIn() až za voláním parent::startup(); ????

Omlouvám se, přesně tuto informaci jsem chtěl původně do dotazu uvést a zapomněl jsem. Ano, ve startup metodě volám jako první příkaz parent::startup();

ViPEr*CZ*
Člen | 817
+
0
-

@premek_k Tak ono to je takhle asi nejlépe. Zavoláš předka, ten něco udělá a ty s tím za tím voláním dál operuješ. Je to obdobný jako psal kolega, že může ověřovat až v action. No protože se mu zavolá něco v předkovi. Samozřejmě od toho chce kapánek uvažovat pokud přepisuji nějakou metodu z předka, co tím vlastně působím a tak trochu je zde nutnost znalosti toho co ona metoda má vlastně dělat.

Lukáš Kadlec
Člen | 17
+
0
-

checkRequirements je zřejmě to co jsem hledal, sice se z nějakého, mně nepochopitelného, důvodu volá při jednom requestu dvakrát, jednou je nepřihlášen a podruhé ano, ale to už vyřeší podmínka. Nějaké námitky k řešení? :)

public function checkRequirements($element) {
	parent::checkRequirements($element);
	if ($this->user->isLoggedIn()) {
		$resource = $this->name . ':' . $this->action;
		if (!$this->user->isAllowed($resource)) {
			// Access denied
		}
	}
}
premek_k
Člen | 172
+
0
-

@ViPEr*CZ* Jistě, to je jasné. Já jen reprodukoval informaci od kolegy, který se s tím taky pral a nakonec to vyřešil tak, jak jsem napsal. Omlouvám se za neověřený tip.

Nicméně z posledního příspěvku Lukáše Kadlece jsem pochopil, že i když volá parent::startup();, tak mu to ověření nefunguje. Je to tak?

pata.kusik111
Člen | 78
+
+1
-

Lukáš Kadlec napsal(a):

checkRequirements je zřejmě to co jsem hledal, sice se z nějakého, mně nepochopitelného, důvodu volá při jednom requestu dvakrát, jednou je nepřihlášen a podruhé ano, ale to už vyřeší podmínka. Nějaké námitky k řešení? :)

public function checkRequirements($element) {
	parent::checkRequirements($element);
	if ($this->user->isLoggedIn()) {
		$resource = $this->name . ':' . $this->action;
		if (!$this->user->isAllowed($resource)) {
			// Access denied
		}
	}
}

checkRequirements se volá

  1. nad samotným presenterem
  2. nad metodou action* (pokud existuje)
  3. nad metodou handle* (pokud existuje)
  4. nad metodou render* (pokud existuje)

(shameless plug: jednoduché zabezpečení akcí pomocí annotací)

Editoval pata.kusik111 (3. 3. 2016 11:23)

ViPEr*CZ*
Člen | 817
+
0
-

@premek_k No v tom případě by to měl být bug, protože podle dokumentace co jsem poslal odkaz by to fungovat mělo.

@LukášKadlec Jak jste to měl v té metodě startup??? Volal jste to až za parent::startup(); ???

@pata.kusik111 To vypadá celkem zajímavě. Doplnil bych jen do dokumentace instalaci přes composer. A dále jak zachytím výjimku? Pokud nemám oprávnění, tak podle zdroje dojde k výjimce s nějakým aglickým textem a nevím kde bych jí měl odchytit, když se to děje magicky?

Btw to s tím startup() Vám ani jednomu nejde?

Lukáš Kadlec
Člen | 17
+
0
-

@ViPEr*CZ* V nejposlednějším potomkovi presenteru jsem volal parent::startup(); a následně isLoggedIn. Při prvním volání, kdy uživatel není přihlášený a k přihlášení dojde v rodiči presenteru, vrací isLoggedIn (na konci startupu) false. V action je true. Pokud přistoupí znovu, má cookie (přihlášen z předchozího volání) vrátí isLoggedIn ve startupu true.

ViPEr*CZ*
Člen | 817
+
0
-

@LukášKadlec Ty jo nějak jsem to nepochopil. Když se dívám na metodu login, která zajistí zalogování uživatele a ta má v sobě něco jako $this->storage->setAuthenticated(TRUE); tak isLoggedIn() už jen ověřuje tuto hodnotu:

public function isLoggedIn()
{
   return $this->storage->isAuthenticated();
}

Takže v podstatě v session mi sedí tato informace zda jsem přihlášen či nikoliv.
Nevím něco mi tu smrdí… asi možná ukázat kód?
Respektive, když zavolám $this->user->login(…); a dojde k úspěšnému zalogování (vytvoření Identity), tak následné volání $this->user->isLoggedIn() by mělo vracet true, protože se mi do mojí session uložila informace o přihlášení uživatele. To by mělo fungovat odkudkoliv jestli se nepletu.

CZechBoY
Člen | 3608
+
0
-

Nenastavuješ někde user storage?

pata.kusik111
Člen | 78
+
0
-

@pata.kusik111 To vypadá celkem zajímavě. Doplnil bych jen do dokumentace instalaci přes composer. A dále jak zachytím výjimku? Pokud nemám oprávnění, tak podle zdroje dojde k výjimce s nějakým aglickým textem a nevím kde bych jí měl odchytit, když se to děje magicky?

@ViPEr*CZ* Pokud ti nevyhovuje defaultní chování (to jest Nette ty přesměruje a vypíše standradní šablonu), tak máš dvě možnosti. Pokud rozšiřuješ ten presenter, tak něco ve smyslu:

public function checkRequirements($element) {
	try {
		parent::checkRequirements($element)
	} catch(ForbiddenRequestException $e) {
		//vlastní zpracování chyby
	}
}

a obdobně pro createComponent

Pokud používáš trait, tak logika je stejná, jenom přejmenuješ metodu pomocí use(kvůli kolizím) a voláš jí po tom parent::checkRequirements($element).

mates
Člen | 36
+
0
-

@LukášKadlec, @premek_k Vrátím se úplně na začátek k původní otázce. Píšete, že používáte „API s drahak/restful a basic auth“.

V dokumentaci drahak/restful se píše:
BasicAuthentication:
Tip: Be careful using this authentication (and standard things such as user's Identity). Remember to keep REST API stateless. Being pragmatic, this is not a good approach but it's the simplest one.

Není ten problém právě s kombinací RESTFul a BasicAuth? Zkuste se podívat na tu dokumentaci zabezpečení API, implementujte vhodnější Auth než Basic.

Když se podíváte do té dokumentace, uvidíte hned kde se auth provádí.

Editoval mates (4. 3. 2016 8:40)

ViPEr*CZ*
Člen | 817
+
0
-

@pata.kusik111 Spíš jsem myslel to dát přímo do dokumentace na githubu, takhle abych to lovil ze src. Jinak samozřejmě díky za vysvětlení. :-)
Standardní chování Nette s touhle hláškou bych asi osobně neukazoval českému uživateli. Btw kam mě vlastně přesměruje Nette na standardní šablonu??? Tohle nějak neznám. Myslíš na ErrorPresenter? V tom případě standardní ErrorPresenter neumí zachytit ForbiddenRequestException pokud se nepletu a hodilo by to chybu 500? Ouvej tak to by opět asi nebylo moc hezké. V tom případě opět navrhuji dát do dokumentace toto objasnění. ;-)

pata.kusik111
Člen | 78
+
0
-

ViPErCZ napsal(a):

@pata.kusik111 Spíš jsem myslel to dát přímo do dokumentace na githubu, takhle abych to lovil ze src. Jinak samozřejmě díky za vysvětlení. :-)
Standardní chování Nette s touhle hláškou bych asi osobně neukazoval českému uživateli. Btw kam mě vlastně přesměruje Nette na standardní šablonu??? Tohle nějak neznám. Myslíš na ErrorPresenter? V tom případě standardní ErrorPresenter neumí zachytit ForbiddenRequestException pokud se nepletu a hodilo by to chybu 500? Ouvej tak to by opět asi nebylo moc hezké. V tom případě opět navrhuji dát do dokumentace toto objasnění. ;-)

Děkuji za doporučení, během víkendu určitě zapracuji. Nicméně ForbiddenRequestException je subclass BadRequestException, kterou ErrorPresenter standardně zachytává a zobrazí šablonu 403.

Editoval pata.kusik111 (4. 3. 2016 8:55)

ViPEr*CZ*
Člen | 817
+
0
-

Ah to se omlouvám, nekoukal jsem jestli je to něčí derivát. Ale vrtalo mi to hlavou podle jména té exception, že mi tam 5ti kilčo nesedí. Nachytal jsi mě na švestkách. :-) Trochu přemýšlím jestli to řešit v ErrorPresenteru. Ale jo asi by se to dalo… a en message si tam třeba nechat přeložit na něco čemu cz user rozumí. Ale do dokumentace bych info o jakou instanci exception se jedná bych dal, kdyby to chtěl někdo dál zpracovávat ;-) Díky.

pata.kusik111 napsal(a):

ViPErCZ napsal(a):

@pata.kusik111 Spíš jsem myslel to dát přímo do dokumentace na githubu, takhle abych to lovil ze src. Jinak samozřejmě díky za vysvětlení. :-)
Standardní chování Nette s touhle hláškou bych asi osobně neukazoval českému uživateli. Btw kam mě vlastně přesměruje Nette na standardní šablonu??? Tohle nějak neznám. Myslíš na ErrorPresenter? V tom případě standardní ErrorPresenter neumí zachytit ForbiddenRequestException pokud se nepletu a hodilo by to chybu 500? Ouvej tak to by opět asi nebylo moc hezké. V tom případě opět navrhuji dát do dokumentace toto objasnění. ;-)

Děkuji za doporučení, během víkendu určitě zapracuji. Nicméně ForbiddenRequestException je subclass BadRequestException, kterou ErrorPresenter standardně zachytává a zobrazí šablonu 403.