Kako uporabljati atribut #[Requires]
Ko pišete spletno aplikacijo, se pogosto srečate s potrebo po omejitvi dostopa do določenih delov vaše
aplikacije. Morda želite, da lahko nekateri zahtevki pošiljajo podatke samo s pomočjo obrazca (torej z metodo POST), ali da
so dostopni samo za AJAX klice. V Nette Frameworku 3.2 se je pojavilo novo orodje, ki vam omogoča takšne omejitve nastaviti
zelo elegantno in pregledno: atribut #[Requires]
.
Atribut je posebna oznaka v PHP, ki jo dodate pred definicijo razreda ali metode. Ker gre pravzaprav za razred, da bi vam naslednji primeri delovali, je treba navesti klavzulo use:
use Nette\Application\Attributes\Requires;
Atribut #[Requires]
lahko uporabite pri samem razredu presenterja in tudi na teh metodah:
action<Action>()
render<View>()
handle<Signal>()
createComponent<Name>()
Zadnji dve metodi se nanašata tudi na komponente, torej atribut lahko uporabljate tudi pri njih.
Če pogoji, ki jih atribut navaja, niso izpolnjeni, pride do sprožitve HTTP napake 4xx.
Metode HTTP
Lahko specificirate, katere HTTP metode (kot GET, POST itd.) so za dostop dovoljene. Na primer, če želite dovoliti dostop samo s pošiljanjem obrazca, nastavite:
class AdminPresenter extends Nette\Application\UI\Presenter
{
#[Requires(methods: 'POST')]
public function actionDelete(int $id): void
{
}
}
Zakaj bi morali uporabljati POST namesto GET za akcije, ki spreminjajo stanje, in kako to storiti? Preberite navodilo.
Lahko navedete metodo ali polje metod. Poseben primer je vrednost '*'
, ki dovoli vse metode, kar standardno
presenterji iz varnostnih razlogov ne
dovoljujejo.
AJAX klici
Če želite, da je presenter ali metoda dostopna samo za AJAX zahtevke, uporabite:
#[Requires(ajax: true)]
class AjaxPresenter extends Nette\Application\UI\Presenter
{
}
Isti izvor
Za povečanje varnosti lahko zahtevate, da je zahtevek narejen iz iste domene. S tem preprečite ranljivost CSRF:
#[Requires(sameOrigin: true)]
class SecurePresenter extends Nette\Application\UI\Presenter
{
}
Pri metodah handle<Signal>()
je dostop iz iste domene zahtevan samodejno. Torej, če nasprotno želite
dovoliti dostop iz katerekoli domene, navedite:
#[Requires(sameOrigin: false)]
public function handleList(): void
{
}
Dostop prek posredovanja
Včasih je koristno omejiti dostop do presenterja tako, da je dostopen samo posredno, na primer z uporabo metode
forward()
ali switch()
iz drugega presenterja. Tako se na primer ščitijo error-presenterji, da jih ni
mogoče poklicati iz URL-ja:
#[Requires(forward: true)]
class ForwardedPresenter extends Nette\Application\UI\Presenter
{
}
V praksi je pogosto treba označiti določene poglede (views), do katerih je mogoče priti šele na podlagi logike v presenterju. Torej spet, da jih ni mogoče odpreti neposredno:
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
{
}
}
Konkretne akcije
Lahko tudi omejite, da bo določena koda, na primer ustvarjanje komponente, dostopna samo za specifične akcije v presenterju:
class EditDeletePresenter extends Nette\Application\UI\Presenter
{
#[Requires(actions: ['add', 'edit'])]
public function createComponentPostForm()
{
}
}
V primeru ene akcije ni treba zapisovati polja: #[Requires(actions: 'default')]
Lastni atributi
Če želite atribut #[Requires]
uporabiti večkrat z isto nastavitvijo, si lahko ustvarite lasten atribut, ki bo
dedoval #[Requires]
in ga nastavil po potrebi.
Na primer #[SingleAction]
bo omogočil dostop samo prek akcije default
:
#[\Attribute]
class SingleAction extends Nette\Application\Attributes\Requires
{
public function __construct()
{
parent::__construct(actions: 'default');
}
}
#[SingleAction]
class SingleActionPresenter extends Nette\Application\UI\Presenter
{
}
Ali #[RestMethods]
bo omogočil dostop prek vseh HTTP metod, uporabljenih za REST API:
#[\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
{
}
Zaključek
Atribut #[Requires]
vam daje veliko fleksibilnosti in nadzora nad tem, kako so vaše spletne strani dostopne.
S pomočjo preprostih, a močnih pravil lahko povečate varnost in pravilno delovanje vaše aplikacije. Kot vidite, lahko uporaba
atributov v Nette vaše delo ne samo olajša, ampak tudi zavaruje.