POST Bağlantıları Doğru Şekilde Nasıl Kullanılır

Web uygulamalarında, özellikle yönetim arayüzlerinde, sunucunun durumunu değiştiren eylemlerin HTTP GET metoduyla yapılmaması temel bir kural olmalıdır. Adından da anlaşılacağı gibi GET yalnızca veri almak için kullanılmalı, veriyi değiştirmek için değil. Kayıt silme gibi eylemlerde POST metodu daha uygundur. DELETE metodu ideal olurdu, ama JavaScript olmadan çağrılamaz; bu yüzden bu tür eylemlerde tarihsel olarak POST kullanılmıştır.

Bu pratikte nasıl gerçekleştirilir? Şu basit numarayı kullanın. Yerleşim şablonunuzun başında postForm kimliğine sahip bir yardımcı form oluşturun. Ardından bu formu silme düğmeleri gibi eylemlerde kullanırsınız:

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

Bu form sayesinde, standart bir <a> bağlantısı yerine bir <button> kullanabilirsiniz. Bu düğme, sıradan bir bağlantı gibi görünecek şekilde biçimlendirilebilir. Örneğin Bootstrap CSS framework'ü btn btn-link sınıflarını sunar; bu da düğmeyi diğer bağlantılardan görsel olarak ayırt edilemez kılar. form="postForm" niteliğiyle düğmeyi hazırladığınız yardımcı forma bağlayın:

<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>

Bu düğmeye tıklamak artık delete eylemini çağırır. İsteklerin yalnızca POST metoduyla kabul edilmesini ve aynı alan adından gelmesini sağlamak için (CSRF saldırılarına karşı etkili bir savunma) #[Requires] attribute'unu 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');
	}
}

Bu attribute, Nette Application 3.2 sürümünden beri kullanılabilir. Yetenekleri hakkında daha fazlasını #Requires attribute'u nasıl kullanılır sayfasında öğrenebilirsiniz.

actionDelete() eylemi yerine handleDelete() sinyalini kullanıyorsanız, sameOrigin: true belirtmeye gerek yoktur; çünkü sinyallerde bu koruma varsayılan olarak açıktır:

#[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, doğru web standartlarına ve uygulamalarına bağlı kalmayı da teşvik eder. Durum değiştiren eylemlerde POST metodunu kullanmak, daha sağlam ve daha güvenli bir uygulama demektir.