#[Requires]
Niteliği Nasıl Kullanılır
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 bazı isteklerin yalnızca bir form kullanarak (yani POST metoduyla) veri gönderebilmesini veya
yalnızca AJAX çağrıları için erişilebilir olmasını istersiniz. Nette Framework 3.2'de, bu tür kısıtlamaları çok
zarif ve anlaşılır bir şekilde ayarlamanıza olanak tanıyan yeni bir araç ortaya çıktı: #[Requires]
niteliği.
Nitelik, bir sınıf veya metot tanımının önüne eklediğiniz PHP'deki özel bir işarettir. Aslında bir sınıf olduğu için, aşağıdaki örneklerin çalışması için use ifadesini belirtmek gerekir:
use Nette\Application\Attributes\Requires;
#[Requires]
niteliğini presenter sınıfının kendisinde ve ayrıca şu metotlarda kullanabilirsiniz:
action<Action>()
render<View>()
handle<Signal>()
createComponent<Name>()
Son iki metot bileşenlerle de ilgilidir, yani niteliği onlarda da kullanabilirsiniz.
Niteliğin belirttiği koşullar karşılanmazsa, bir HTTP 4xx hatası tetiklenir.
HTTP Metotları
Erişim için hangi HTTP metotlarının (GET, POST vb. gibi) izinli olduğunu belirleyebilirsiniz. Örneğin, yalnızca bir form göndererek erişime izin vermek istiyorsanız, şunu ayarlarsınız:
class AdminPresenter extends Nette\Application\UI\Presenter
{
#[Requires(methods: 'POST')]
public function actionDelete(int $id): void
{
}
}
Durumu değiştiren eylemler için neden GET yerine POST kullanmalısınız ve bunu nasıl yapmalısınız? Kılavuzu okuyun.
Bir metot veya metot dizisi belirtebilirsiniz. Özel bir durum, tüm metotlara izin veren '*'
değeridir, ki bu
presenter'ların standart olarak güvenlik
nedenleriyle izin vermediği bir durumdur.
AJAX Çağrıları
Bir presenter veya metodun yalnızca AJAX istekleri için kullanılabilir olmasını istiyorsanız, şunu kullanın:
#[Requires(ajax: true)]
class AjaxPresenter extends Nette\Application\UI\Presenter
{
}
Aynı Kaynak
Güvenliği artırmak için, isteğin aynı alan adından yapılmasını zorunlu kılabilirsiniz. Bu, CSRF güvenlik açığını önler:
#[Requires(sameOrigin: true)]
class SecurePresenter extends Nette\Application\UI\Presenter
{
}
handle<Signal>()
metotlarında, aynı alan adından erişim otomatik olarak zorunlu kılınır.
Dolayısıyla tam tersine, herhangi bir alan adından erişime izin vermek istiyorsanız, şunu belirtin:
#[Requires(sameOrigin: false)]
public function handleList(): void
{
}
Forward ile Erişim
Bazen bir presenter'a erişimi yalnızca dolaylı olarak, örneğin başka bir presenter'dan forward()
veya
switch()
metodunu kullanarak kullanılabilir olacak şekilde kısıtlamak yararlıdır. Örneğin error-presenter'lar
bu şekilde korunur, böylece URL'den çağrılamazlar:
#[Requires(forward: true)]
class ForwardedPresenter extends Nette\Application\UI\Presenter
{
}
Pratikte, presenter'daki mantığa dayalı olarak erişilebilen belirli view'leri işaretlemek genellikle gereklidir. Yani yine, doğrudan açılamamaları için:
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
{
}
}
Belirli Eylemler
Ayrıca, belirli bir kodun, örneğin bir bileşenin oluşturulmasının, yalnızca presenter'daki belirli eylemler için kullanılabilir olmasını da kısıtlayabilirsiniz:
class EditDeletePresenter extends Nette\Application\UI\Presenter
{
#[Requires(actions: ['add', 'edit'])]
public function createComponentPostForm()
{
}
}
Tek bir eylem durumunda, bir dizi yazmaya gerek yoktur: #[Requires(actions: 'default')]
Özel Nitelikler
#[Requires]
niteliğini aynı ayarlarla tekrar tekrar kullanmak istiyorsanız, #[Requires]
'ı miras
alan ve onu ihtiyaçlara göre ayarlayan kendi niteliğinizi oluşturabilirsiniz.
Ö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
{
}
Veya #[RestMethods]
, REST API için kullanılan tüm HTTP metotları aracılığıyla erişime izin verir:
#[\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ç
#[Requires]
niteliği, web sayfalarınızın nasıl erişilebilir olduğu konusunda size büyük esneklik ve
kontrol sağlar. Basit ama güçlü kurallar kullanarak uygulamanızın güvenliğini ve doğru çalışmasını
artırabilirsiniz. Gördüğünüz gibi, Nette'de nitelikleri kullanmak işinizi yalnızca kolaylaştırmakla kalmaz, aynı
zamanda güvence altına da alabilir.