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.