Hogyan kell helyesen használni a POST linkeket
A webes alkalmazásokban, különösen az adminisztrációs felületeken alapvető szabály kell, hogy legyen, hogy a kiszolgáló állapotát megváltoztató műveleteket nem szabad a HTTP GET módszerrel végrehajtani. Ahogy a módszer neve is sugallja, a GET csak adatok lekérdezésére használható, azok megváltoztatására nem. Az olyan műveletekhez, mint például a rekordok törlése, célszerűbb a POST módszert használni. Bár az ideális a DELETE módszer használata lenne, ez nem hívható elő JavaScript nélkül, ezért a POST módszert használják.
Hogyan kell ezt a gyakorlatban csinálni? Használja ezt az egyszerű trükköt. A sablon elején hozzon létre egy
segédűrlapot a postForm
azonosítóval, amelyet aztán a törlés gombokhoz fog használni:
<form method="post" id="postForm"></form>
Ezzel az űrlappal használhat egy <button>
a klasszikus <a>
link helyett, amely
vizuálisan úgy módosítható, hogy úgy nézzen ki, mint egy hagyományos link. A Bootstrap CSS keretrendszer például a
btn btn-link
osztályokat kínálja, amelyek lehetővé teszik, hogy a gomb vizuálisan megkülönböztethetetlen
legyen más linkektől. A form="postForm"
attribútum segítségével az előre elkészített űrlapra
linkeljük:
<table>
<tr n:foreach="$posts as $post">
<td>{$post->title}</td>
<td>
<button class="btn btn-link" form="postForm" formaction="{link delete $post->id}">delete</button>
<!-- instead of <a n:href="delete $post->id">delete</a> -->
</td>
</tr>
</table>
A linkre kattintva mostantól a delete
műveletet hívjuk elő. Annak biztosítására, hogy a kéréseket csak
POST módszerrel és ugyanabból a tartományból fogadjuk el (ami hatékony védekezés a CSRF-támadások ellen), használjuk 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); // hypothetical code for deleting a record
$this->redirect('default');
}
}
Az attribútum a Nette Application 3.2 óta áll rendelkezésre, és lehetőségeiről többet megtudhat a Hogyan használjuk a #Requires attribútumot című oldalon.
Ha a actionDelete()
művelet helyett a handleDelete()
jelet használná, nem szükséges a
sameOrigin: true
megadása, mivel a jeleknél ez a védelem implicit módon van beá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 az alkalmazás biztonságát javítja, hanem hozzájárul a megfelelő webes szabványok és gyakorlatok betartásához is. A POST-módszerek használatával az állapotváltoztató műveletekhez robusztusabb és biztonságosabb alkalmazást érhet el.