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.