Kontrola přihlášení na všech stránkách

tichopad
Člen | 4
+
0
-

Zdravím,
s nette teprve začínám, tak se jedná možná o triviální dotaz, ale potřeboval bych zabezpečit celý systém tak, aby do něj mohli jen přihlášení uživatelé? Když jsem procházel manuál a nějaké dotazy na webu, tak jsem našel zmínku o tom, že bych měl v každém presenteru vytvořit startup funkci a v ní kontrolovat přihlášení. To mi ale přijde dost krkolomné :-( Ještě mě napadlo vytvořit si vlastní BasePresenter a v něm to ošetřit a od toho presenteru dělat extends na všechny další, ale zase hrozí, že tam někdo tuto funkci přepíše a tím vyřadí zabezpečení z provozu.
Je nějaké elegantnější řešení, jak kontrolovat přihlášení? Např. pomocí routování ověřit, zda je uživatel přihlášený a zobrazit mu defaultní stránku po přihlášení a pokud ne, tak zobrazit login form?
Díky za nakopnutí.
Honza

Marek Bartoš
Nette Blogger | 1275
+
0
-

Zkus mrknout na toto, pro inspiraci:

V BasePresenter->startup() definuje, že presenter musí definovat, zda je potřeba přihlášení https://github.com/…resenter.php#…

BaseAdminPresenter a BaseFrontPresenter definují, že vždy vyžadují přihlášení https://github.com/…resenter.php#…

A konkrétní presentery, které login nevyžadují, mohou použít traitu NoLogin nebo přetížit metodu isLoginRequired(), aby kontrolu oprávnění vyřadily https://github.com/…/NoLogin.php

Metodu startup() bys mohl případně označit jako finální, aby nehrozilo, že ji podědíš a zapomeneš zavolat parent. Na startup se případně vždy dá navěsit takto, se zneužitím toho, že nette/di volá na presenteru inject* metody:

class ExamplePresenter extends \Nette\Application\UI\Presenter
{
  public function injectNothing(): void
  {
    $this->onStartup[] = function(): void {
      // Your startup code
    }
  }
}

Např. pomocí routování ověřit, zda je uživatel přihlášený

Router se snaž držet co nejjednodušší. Většinou je snazší feature implementovat v presenteru a příliš chytrý router má tendenci bobtnat a způsobovat cyklické závislosti, které se pak řeší dost komplikovaně.

Editoval Mabar (12. 4. 2021 11:37)

Kamil Valenta
Člen | 820
+
0
-

Já u presenterů, které vyžadují ověření, používám traitu „SecurePresenter“, která implementuje metodu „checkRequirements“.

Marek Bartoš
Nette Blogger | 1275
+
0
-

checkRequirements() bude asi o chlup lepší :) Volají se v pořadí checkRequirements(), onStartup[], startup(), takže v závislosti na tom, na co se onStartup[] používá to může být praktičtější.

SecurePresenter jsem též používal, ale je to nebezpečné v tom, že můžeš zapomenout presenter zabezpečit zatímco při opačném postupu nejhorší co se stane je, že se nepřihlášený uživatel nedostane, kam se dostat má.

Milo
Nette Core | 1283
+
0
-

tichopad napsal(a):

ale zase hrozí, že tam někdo tuto funkci přepíše a tím vyřadí zabezpečení z provozu.

Ano, je to možné, ale ne úplně přímočaré. Nette\Application\UI\Presenter totiž kontroluje, že potomek volá jeho startup() metodu. Tedy pokud ji potomek tvého BasePresenter nezavolá, vyskočí výjimka. To ovšem může potomoek obejít tím, že nebude volat parent::startup(), ale Nette\Application\UI\Presenter::startup().

Pokud se ti řešení se startup() metodou líbí a chceš si být jistější, můžeš:

abstract class BasePresenter extends ...
{
	final public function startup()  # <-- je final
	{
		# ... kontrola přihlášení
		$this->childStartup();
	}

	public function childStartup()  # <-- tuhle může přetížit potomek
	{
	}
}

Ale díky reflexi v PHP by se to stejně asi nějak dalo očurat, asi jako jakékoliv jiné řešení. Zkrátka musíš vědět, že ten „někdo“, o kterém píšeš, to očurat nechce.

Kamil Valenta
Člen | 820
+
0
-

Mabar napsal(a):

SecurePresenter jsem též používal, ale je to nebezpečné v tom, že můžeš zapomenout presenter zabezpečit

Tak samozřejmě můžeš tu traitu plácnout do BasePresenteru a je to rovnocenné.
Zapomenutou Secure traitu by nám odhalily integrační testy.

Ale dal jsem to samozřejmě jen jako tip na jedno z mnoha pojetí. Rozhodující může být i podíl zabezpečených presenterů vs. frontendových…

tichopad
Člen | 4
+
0
-

Ale dal jsem to samozřejmě jen jako tip na jedno z mnoha pojetí. Rozhodující může být i podíl zabezpečených presenterů vs. frontendových…

Zabezpečené jsou v podstatě všechny krom logovacího formuláře. Přepisuju interní systém z dob dávno minulých do moderní a udržitelné podoby za využití aktuálních verzí PHP, DB…

Každopádně díky všem za odpovědi. Popravdě jsem nečekal ani tak rychlou ani tak velkou odezvu. Jdu zkoušet a uvidíme, jak to dopadne.