POST bağlantıları nasıl doğru kullanılır

Web uygulamalarında, özellikle yönetim arayüzlerinde, sunucu durumunu değiştiren eylemlerin HTTP GET metodu aracılığıyla gerçekleştirilmemesi temel bir kural olmalıdır. Metodun adından da anlaşılacağı gibi, GET yalnızca veri almak için kullanılmalı, değiştirmek için değil. Kayıt silme gibi eylemler için POST metodunu kullanmak daha uygundur. İdeal olan DELETE metodu olsa da, JavaScript olmadan çağrılamaz, bu nedenle tarihsel olarak POST kullanılır.

Pratikte nasıl yapılır? Bu basit hileyi kullanın. Şablonun başında, postForm tanımlayıcısına sahip yardımcı bir form oluşturursunuz, bunu daha sonra silme düğmeleri için kullanırsınız:

<form method="post" id="postForm"></form>

Bu form sayesinde, klasik bir <a> bağlantısı yerine, görsel olarak normal bir bağlantı gibi görünecek şekilde ayarlanabilen bir <button> düğmesi kullanabilirsiniz. Örneğin, Bootstrap CSS framework'ü, düğmenin diğer bağlantılardan görsel olarak farklı olmamasını sağlayan btn btn-link sınıflarını sunar. form="postForm" niteliğini kullanarak onu önceden hazırlanmış formla ilişkilendiririz:

<table>
	<tr n:foreach="$posts as $post">
		<td>{$post->title}</td>
		<td>
			<button class="btn btn-link" form="postForm" formaction="{link delete $post->id}">sil</button>
			<!-- <a n:href="delete $post->id">sil</a> yerine -->
		</td>
	</tr>
</table>

Bağlantıya tıklandığında, şimdi delete eylemi çağrılır. İsteklerin yalnızca POST metodu aracılığıyla ve aynı etki alanından kabul edilmesini sağlamak için (bu, CSRF saldırılarına karşı etkili bir savunmadır), #[Requires] niteliğini kullanın:

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); // kaydı silen varsayımsal kod
		$this->redirect('default');
	}
}

Nitelik Nette Application 3.2'den beri mevcuttur ve yetenekleri hakkında daha fazla bilgiyi Requires niteliği nasıl kullanılır sayfasında bulabilirsiniz.

actionDelete() eylemi yerine handleDelete() sinyalini kullanıyorsanız, sinyallerin bu koruması örtük olarak ayarlandığından sameOrigin: true belirtmek gerekli değildir:

#[Requires(methods: 'POST')]
public function handleDelete(int $id): void
{
	$this->facade->deletePost($id);
	$this->redirect('this');
}

Bu yaklaşım yalnızca uygulamanızın güvenliğini artırmakla kalmaz, aynı zamanda doğru web standartlarına ve uygulamalarına uymaya da katkıda bulunur. Durumu değiştiren eylemler için POST yöntemlerini kullanarak daha sağlam ve güvenli bir uygulama elde edersiniz.