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.