Hogyan használjuk helyesen a POST linkeket
Webalkalmazásokban, különösen adminisztrációs felületeken, alapvető szabálynak kellene lennie, hogy a szerver állapotát megváltoztató műveleteket ne a GET HTTP metódussal végezzük. Ahogy a metódus neve is sugallja, a GET csak adatok lekérésére szolgál, nem pedig azok megváltoztatására. Olyan műveletekhez, mint például a rekordok törlése, célszerűbb a POST metódust használni. Bár ideális a DELETE metódus lenne, de azt JavaScript nélkül nem lehet meghívni, ezért történelmileg a POST-ot használják.
Hogyan tegyük ezt a gyakorlatban? Használja ezt az egyszerű trükköt. A sablon elején hozzon létre egy segédűrlapot
postForm azonosítóval, amelyet aztán a törlő gombokhoz használ:
<form method="post" id="postForm"></form>
Ennek az űrlapnak köszönhetően a klasszikus <a> link helyett használhat egy <button>
gombot, amelyet vizuálisan úgy lehet módosítani, hogy úgy nézzen ki, mint egy normál link. Például a Bootstrap CSS
keretrendszer btn btn-link osztályokat kínál, amelyekkel elérheti, hogy a gomb vizuálisan ne különbözzön a
többi linktől. A form="postForm" attribútummal összekapcsoljuk az előkészített űrlappal:
<table>
<tr n:foreach="$posts as $post">
<td>{$post->title}</td>
<td>
<button class="btn btn-link" form="postForm" formaction="{link delete $post->id}">törlés</button>
<!-- <a n:href="delete $post->id">törlés</a> helyett -->
</td>
</tr>
</table>
A linkre kattintva most a delete akció hívódik meg. Annak biztosítására, hogy a kérések csak a POST
metóduson keresztül és ugyanarról a domainről érkezzenek (ami hatékony védelem a CSRF támadások ellen), használja a
#[Requires] attribútumot:
use Nette\Application\Attributes\Requires;
class AdminPresenter extends Nette\Application\UI\Presenter
{
#[Requires(methods: 'POST', sameOrigin: true)]
public function actionDelete(int $id): void
{
$this->facade->deletePost($id); // hipotetikus kód a rekord törlésére
$this->redirect('default');
}
}
Az attribútum a Nette Application 3.2 óta létezik, és további lehetőségeiről a Hogyan használjuk a #Requires attribútumot oldalon olvashat többet.
Ha az actionDelete() akció helyett a handleDelete() signált használná, nem szükséges megadni a
sameOrigin: true-t, mert a signáloknak ez a védelme alapértelmezetten be van állítva:
#[Requires(methods: 'POST')]
public function handleDelete(int $id): void
{
$this->facade->deletePost($id);
$this->redirect('this');
}
Ez a megközelítés nemcsak javítja az alkalmazás biztonságát, hanem hozzájárul a helyes webes szabványok és gyakorlatok betartásához is. A POST metódusok használatával az állapotot megváltoztató műveletekhez robusztusabb és biztonságosabb alkalmazást érhet el.