Hogyan használjuk a #[Requires]
attribútumot
Amikor webalkalmazást ír, gyakran találkozik azzal az igénnyel, hogy korlátozza a hozzáférést az
alkalmazás bizonyos részeihez. Talán azt szeretné, hogy bizonyos kérések csak űrlapon keresztül küldhessenek adatokat
(azaz POST metódussal), vagy hogy csak AJAX hívások számára legyenek elérhetők. A Nette Framework 3.2-ben megjelent egy
új eszköz, amely lehetővé teszi az ilyen korlátozások nagyon elegáns és áttekinthető beállítását: a
#[Requires]
attribútum.
Az attribútum egy speciális jelölés a PHP-ban, amelyet az osztály vagy metódus definíciója elé adunk hozzá. Mivel valójában egy osztályról van szó, ahhoz, hogy a következő példák működjenek, meg kell adni a use klauzult:
use Nette\Application\Attributes\Requires;
A #[Requires]
attribútumot használhatja magánál a presenter osztálynál és ezeknél a
metódusoknál is:
action<Action>()
render<View>()
handle<Signal>()
createComponent<Name>()
Az utolsó két metódus a komponensekre is vonatkozik, tehát az attribútumot náluk is használhatja.
Ha az attribútum által megadott feltételek nem teljesülnek, HTTP 4xx hiba váltódik ki.
HTTP metódusok
Megadhatja, hogy mely HTTP metódusok (mint GET, POST stb.) engedélyezettek a hozzáféréshez. Például, ha csak űrlapküldéssel szeretné engedélyezni a hozzáférést, állítsa be:
class AdminPresenter extends Nette\Application\UI\Presenter
{
#[Requires(methods: 'POST')]
public function actionDelete(int $id): void
{
}
}
Miért kellene POST-ot használnia GET helyett az állapotot megváltoztató akciókhoz, és hogyan tegye ezt? Olvassa el az útmutatót.
Megadhat egy metódust vagy metódusok tömbjét. Speciális eset a '*'
érték, amely minden metódust
engedélyez, amit a presenterek biztonsági
okokból alapértelmezés szerint nem engednek meg.
AJAX hívás
Ha azt szeretné, hogy a presenter vagy metódus csak AJAX kérések számára legyen elérhető, használja:
#[Requires(ajax: true)]
class AjaxPresenter extends Nette\Application\UI\Presenter
{
}
Azonos eredet
A biztonság növelése érdekében megkövetelheti, hogy a kérés ugyanarról a domainről érkezzen. Ezzel megakadályozhatja a CSRF sebezhetőséget:
#[Requires(sameOrigin: true)]
class SecurePresenter extends Nette\Application\UI\Presenter
{
}
A handle<Signal>()
metódusoknál az azonos domainről való hozzáférés automatikusan megkövetelt.
Tehát ha fordítva, bármely domainről szeretné engedélyezni a hozzáférést, adja meg:
#[Requires(sameOrigin: false)]
public function handleList(): void
{
}
Hozzáférés forwardon keresztül
Néha hasznos korlátozni a presenterhez való hozzáférést úgy, hogy csak közvetve legyen elérhető, például a
forward()
vagy switch()
metódus használatával egy másik presenterből. Így védik például az
error-presentereket, hogy ne lehessen őket URL-ből meghívni:
#[Requires(forward: true)]
class ForwardedPresenter extends Nette\Application\UI\Presenter
{
}
A gyakorlatban gyakran szükség van bizonyos view-k megjelölésére, amelyekhez csak a presenter logikája alapján lehet eljutni. Tehát ismét, hogy ne lehessen őket közvetlenül megnyitni:
class ProductPresenter extends Nette\Application\UI\Presenter
{
public function actionDefault(int $id): void
{
$product = $this->facade->getProduct($id);
if (!$product) {
$this->setView('notfound');
}
}
#[Requires(forward: true)]
public function renderNotFound(): void
{
}
}
Konkrét akciók
Korlátozhatja azt is, hogy egy bizonyos kód, például egy komponens létrehozása, csak specifikus akciókhoz legyen elérhető a presenterben:
class EditDeletePresenter extends Nette\Application\UI\Presenter
{
#[Requires(actions: ['add', 'edit'])]
public function createComponentPostForm()
{
}
}
Egyetlen akció esetén nem szükséges tömböt írni: #[Requires(actions: 'default')]
Saját attribútumok
Ha a #[Requires]
attribútumot ismételten ugyanazzal a beállítással szeretné használni, létrehozhat saját
attribútumot, amely örökli a #[Requires]
-t, és az igényeknek megfelelően állítja be.
Például a #[SingleAction]
csak a default
akción keresztül engedélyezi a hozzáférést:
#[\Attribute]
class SingleAction extends Nette\Application\Attributes\Requires
{
public function __construct()
{
parent::__construct(actions: 'default');
}
}
#[SingleAction]
class SingleActionPresenter extends Nette\Application\UI\Presenter
{
}
Vagy a #[RestMethods]
engedélyezi a hozzáférést az összes REST API-hoz használt HTTP metóduson
keresztül:
#[\Attribute]
class RestMethods extends Nette\Application\Attributes\Requires
{
public function __construct()
{
parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
}
}
#[RestMethods]
class ApiPresenter extends Nette\Application\UI\Presenter
{
}
Következtetés
A #[Requires]
attribútum nagy rugalmasságot és kontrollt ad Önnek afölött, hogyan érhetők el a weboldalai.
Egyszerű, de erőteljes szabályok segítségével növelheti alkalmazása biztonságát és helyes működését. Mint
láthatja, az attribútumok használata a Nette-ben nemcsak megkönnyítheti a munkáját, hanem biztonságosabbá is teheti.