Hogyan használjuk a #[Requires]
Attribútum
Webalkalmazások írása során gyakran találkozunk azzal az igénnyel, hogy korlátozni kell az alkalmazás
bizonyos részeihez való hozzáférést. Talán azt szeretné, hogy egyes kérések csak űrlapon keresztül küldhessenek
adatokat (tehát a POST módszerrel), vagy csak AJAX-hívások számára legyenek elérhetők. A Nette Framework 3.2-ben egy új
eszköz került bevezetésre, amely lehetővé teszi az ilyen korlátozások elegáns és egyértelmű beállítását: a
#[Requires]
attribútum.
Az attribútum egy speciális jelölő a PHP-ban, amelyet egy osztály vagy metódus definíciója előtt adunk meg. Mivel lényegében egy osztályról van szó, a következő példák működéséhez a use záradékot is be kell illesztenie:
use Nette\Application\Attributes\Requires;
Használhatja a #[Requires]
attribútumot magával a prezentáló osztállyal és ezekkel a metódusokkal:
action<Action>()
render<View>()
handle<Signal>()
createComponent<Name>()
Az utolsó két módszer szintén komponensekre vonatkozik, így ezekkel is használhatja az attribútumot.
Ha az attribútum által meghatározott feltételek nem teljesülnek, a rendszer egy HTTP 4xx hibaüzenetet küld.
HTTP-módszerek
Megadhatja, hogy mely HTTP-módszerek (például GET, POST stb.) engedélyezettek a hozzáféréshez. Ha például csak egy űrlap elküldésével akarja engedélyezni a hozzáférést, állítsa be a következőket:
class AdminPresenter extends Nette\Application\UI\Presenter
{
#[Requires(methods: 'POST')]
public function actionDelete(int $id): void
{
}
}
Miért érdemes POST-ot használni GET helyett állapotváltoztató műveletekhez, és hogyan kell ezt megtenni? Olvassa el az útmutatót.
Megadhat egy módszert vagy módszerek tömbjét. Speciális eset a '*'
érték, amely minden módszert
engedélyez, amit a prezenterek biztonsági
okokból alapértelmezés szerint nem engedélyeznek.
AJAX hívások
Ha azt szeretné, hogy egy bemutató vagy metódus csak AJAX-kérések számára legyen elérhető, használja a következőt:
#[Requires(ajax: true)]
class AjaxPresenter extends Nette\Application\UI\Presenter
{
}
Ugyanaz az eredet
A biztonság növelése érdekében megkövetelheti, hogy a kérés ugyanarról a tartományról érkezzen. Ez megakadályozza a CSRF sebezhetőséget:
#[Requires(sameOrigin: true)]
class SecurePresenter extends Nette\Application\UI\Presenter
{
}
A oldalon. handle<Signal>()
módszerek esetében automatikusan ugyanabból a tartományból való
hozzáférés szükséges. Ha tehát bármilyen tartományból engedélyezni szeretné a hozzáférést, adja meg:
#[Requires(sameOrigin: false)]
public function handleList(): void
{
}
Hozzáférés a Forwardon keresztül
Néha célszerű úgy korlátozni a hozzáférést egy prezentálóhoz, hogy az csak közvetve legyen elérhető, például egy
másik prezentáló forward()
vagy switch()
módszereivel. A hiba-bemutatókat így védik, hogy
megakadályozzák, hogy egy URL-ből indítsák őket:
#[Requires(forward: true)]
class ForwardedPresenter extends Nette\Application\UI\Presenter
{
}
A gyakorlatban gyakran szükség van bizonyos nézetek megjelölésére, amelyek csak a prezenter logikája alapján érhetők el. Megint csak azért, 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 intézkedések
Azt is korlátozhatja, hogy bizonyos kódok, például egy komponens létrehozása, csak bizonyos műveletek esetén legyenek elérhetők a prezenterben:
class EditDeletePresenter extends Nette\Application\UI\Presenter
{
#[Requires(actions: ['add', 'edit'])]
public function createComponentPostForm()
{
}
}
Egyetlen művelethez nem szükséges tömböt írni: #[Requires(actions: 'default')]
Egyéni attribútumok
Ha a #[Requires]
attribútumot ismételten ugyanazokkal a beállításokkal használni, létrehozhat saját
attribútumot, amely örökli a #[Requires]
és az igényeinek megfelelően állíthatja be.
Például, #[SingleAction]
csak a default
műveleten 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 #[RestMethods]
lehetővé teszi a hozzáférést a REST API-hoz használt összes HTTP-módszeren
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 nagyfokú rugalmasságot és ellenőrzést biztosít a weboldalak elérésének módját
illetően. Egyszerű, de hatékony szabályok használatával fokozhatja az alkalmazás biztonságát és megfelelő
működését. Amint láthatja, az attribútumok használata a Nette-ben nemcsak egyszerűsítheti, hanem biztosíthatja is a
munkáját.