Nasıl Kullanılır #[Requires] Öznitelik

Bir web uygulaması yazarken, uygulamanızın belirli bölümlerine erişimi kısıtlama ihtiyacıyla sık sık karşılaşırsınız. Belki de bazı isteklerin yalnızca bir form aracılığıyla veri gönderebilmesini (dolayısıyla POST yöntemini kullanarak) veya yalnızca AJAX çağrıları tarafından erişilebilir olmasını istiyorsunuzdur. Nette Framework 3.2'de, bu tür kısıtlamaları zarif ve açık bir şekilde ayarlamanıza olanak tanıyan yeni bir araç sunulmuştur: #[Requires] nitelik.

Nitelik, PHP'de bir sınıf veya yöntemin tanımından önce eklediğiniz özel bir işarettir. Esasen bir sınıf olduğu için, aşağıdaki örneklerin çalışması için use cümlesini eklemeniz gerekir:

use Nette\Application\Attributes\Requires;

Kullanabilirsiniz #[Requires] özniteliğinin sunum yapan sınıfın kendisiyle ve bu yöntemlerle olan ilişkisi:

  • action<Action>()
  • render<View>()
  • handle<Signal>()
  • createComponent<Name>()

Son iki yöntem de bileşenlerle ilgilidir, bu nedenle özniteliği onlarla da kullanabilirsiniz.

Öznitelik tarafından belirtilen koşullar karşılanmazsa, bir HTTP 4×x hatası tetiklenir.

HTTP Yöntemleri

Erişim için hangi HTTP yöntemlerine (GET, POST, vb.) izin verileceğini belirtebilirsiniz. Örneğin, yalnızca bir form göndererek erişime izin vermek istiyorsanız, şunu ayarlayın:

class AdminPresenter extends Nette\Application\UI\Presenter
{
	#[Requires(methods: 'POST')]
	public function actionDelete(int $id): void
	{
	}
}

Durum değiştirme eylemleri için neden GET yerine POST kullanmalısınız ve bunu nasıl yapmalısınız? Kılavuzu okuyun.

Bir yöntem veya bir dizi yöntem belirtebilirsiniz. Özel bir durum, sunum yapanların güvenlik nedeniyle varsayılan olarak izin vermediği tüm yöntemleri etkinleştirmek için '*' değeridir.

AJAX Çağrıları

Bir sunucunun veya yöntemin yalnızca AJAX istekleri için erişilebilir olmasını istiyorsanız, şunu kullanın:

#[Requires(ajax: true)]
class AjaxPresenter extends Nette\Application\UI\Presenter
{
}

Aynı Köken

Güvenliği artırmak için, isteğin aynı etki alanından yapılmasını zorunlu tutabilirsiniz. Bu, CSRF'ye karşı güvenlik açığını önler:

#[Requires(sameOrigin: true)]
class SecurePresenter extends Nette\Application\UI\Presenter
{
}

İçin handle<Signal>() yöntemlerinde, aynı etki alanından erişim otomatik olarak gereklidir. Bu nedenle, herhangi bir etki alanından erişime izin vermek istiyorsanız, şunu belirtin:

#[Requires(sameOrigin: false)]
public function handleList(): void
{
}

Forward üzerinden erişim

Bazen bir sunucuya erişimi kısıtlamak yararlı olabilir, böylece yalnızca dolaylı olarak, örneğin başka bir sunucudan forward() veya switch() yöntemleri kullanılarak kullanılabilir. Hata sunucuları, bir URL'den tetiklenmelerini önlemek için bu şekilde korunur:

#[Requires(forward: true)]
class ForwardedPresenter extends Nette\Application\UI\Presenter
{
}

Pratikte, yalnızca sunum yapan kişideki mantığa dayalı olarak erişilebilen belirli görünümleri işaretlemek genellikle gereklidir. Yine, böylece doğrudan açılamazlar:

class ProductPresenter extends Nette\Application\UI\Presenter
{

	public function actionDefault(int $id): void
	{
		$product = this->facade->getProduct($id);
		if (!product) {
			this->setView('notfound');
		}
	}

	#[Requires(forward: true)]
	public function renderNotFound(): void
	{
	}
}

Spesifik Eylemler

Ayrıca, bir bileşen oluşturmak gibi belirli kodların yalnızca sunum aracındaki belirli eylemler için erişilebilir olmasını da kısıtlayabilirsiniz:

class EditDeletePresenter extends Nette\Application\UI\Presenter
{
	#[Requires(actions: ['add', 'edit'])]
	public function createComponentPostForm()
	{
	}
}

Tek bir eylem için bir dizi yazmaya gerek yoktur: #[Requires(actions: 'default')]

Özel Nitelikler

Eğer kullanmak istiyorsanız #[Requires] özniteliğini aynı ayarlarla tekrar tekrar kullanmak istemiyorsanız, kendi özniteliğinizi oluşturabilirsiniz. #[Requires] ve ihtiyaçlarınıza göre ayarlayın.

Örneğin, #[SingleAction] yalnızca default eylemi aracılığıyla erişime izin verir:

#[Attribute]
class SingleAction extends Nette\Application\Attributes\Requires
{
	public function __construct()
	{
		parent::__construct(actions: 'default');
	}
}

#[SingleAction]
class SingleActionPresenter extends Nette\Application\UI\Presenter
{
}

Ya da #[RestMethods] REST API için kullanılan tüm HTTP yöntemleri aracılığıyla erişime izin verecektir:

#[\Attribute]
class RestMethods extends Nette\Application\Attributes\Requires
{
	public function __construct()
	{
		parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
	}
}

#[RestMethods]
class ApiPresenter extends Nette\Application\UI\Presenter
{
}

Sonuç

Bu #[Requires] özelliği, web sayfalarınıza nasıl erişileceği konusunda size büyük esneklik ve kontrol sağlar. Basit ama güçlü kurallar kullanarak uygulamanızın güvenliğini ve düzgün çalışmasını artırabilirsiniz. Gördüğünüz gibi, Nette öznitelikleri kullanmak sadece işinizi basitleştirmekle kalmaz, aynı zamanda güvenli hale de getirir.