Wie man das #[Requires]
Attribut
Wenn Sie eine Webanwendung schreiben, stoßen Sie häufig auf die Notwendigkeit, den Zugriff auf bestimmte Teile
Ihrer Anwendung zu beschränken. Vielleicht möchten Sie, dass einige Anfragen nur Daten über ein Formular senden können (also
die POST-Methode verwenden) oder nur für AJAX-Aufrufe zugänglich sind. In Nette Framework 3.2 wurde ein neues Werkzeug
eingeführt, mit dem Sie solche Einschränkungen elegant und klar festlegen können: das #[Requires]
Attribut.
Das Attribut ist eine spezielle Markierung in PHP, die Sie vor der Definition einer Klasse oder Methode hinzufügen. Da es sich im Wesentlichen um eine Klasse handelt, müssen Sie die Use-Klausel einfügen, damit die folgenden Beispiele funktionieren:
use Nette\Application\Attributes\Requires;
Sie können das #[Requires]
Attribut mit der Presenter-Klasse selbst und mit diesen Methoden verwenden:
action<Action>()
render<View>()
handle<Signal>()
createComponent<Name>()
Die letzten beiden Methoden betreffen auch Komponenten, so dass Sie das Attribut auch für diese verwenden können.
Wenn die durch das Attribut festgelegten Bedingungen nicht erfüllt sind, wird ein HTTP 4xx-Fehler ausgelöst.
HTTP-Methoden
Sie können angeben, welche HTTP-Methoden (wie GET, POST usw.) für den Zugriff zugelassen sind. Wenn Sie beispielsweise den Zugriff nur durch das Absenden eines Formulars erlauben wollen, legen Sie fest:
class AdminPresenter extends Nette\Application\UI\Presenter
{
#[Requires(methods: 'POST')]
public function actionDelete(int $id): void
{
}
}
Warum sollten Sie POST anstelle von GET für zustandsändernde Aktionen verwenden, und wie geht das? Lesen Sie den Leitfaden.
Sie können eine Methode oder eine Reihe von Methoden angeben. Ein Sonderfall ist der Wert '*'
, um alle Methoden
zu aktivieren, was Presenter aus Sicherheitsgründen standardmäßig nicht
zulassen.
AJAX-Aufrufe
Wenn Sie möchten, dass ein Presenter oder eine Methode nur für AJAX-Anfragen zugänglich ist, verwenden Sie:
#[Requires(ajax: true)]
class AjaxPresenter extends Nette\Application\UI\Presenter
{
}
Gleiche Herkunft
Um die Sicherheit zu erhöhen, können Sie verlangen, dass die Anfrage von der gleichen Domäne aus gestellt wird. Dies verhindert eine Anfälligkeit für CSRF:
#[Requires(sameOrigin: true)]
class SecurePresenter extends Nette\Application\UI\Presenter
{
}
Für handle<Signal>()
Methoden ist der Zugriff aus derselben Domäne automatisch erforderlich. Wenn Sie also
den Zugriff aus einer beliebigen Domäne zulassen wollen, geben Sie dies an:
#[Requires(sameOrigin: false)]
public function handleList(): void
{
}
Zugang über Forward
Manchmal ist es sinnvoll, den Zugriff auf einen Präsentator so einzuschränken, dass er nur indirekt verfügbar ist, z. B.
über die Methoden forward()
oder switch()
eines anderen Präsentators. Auf diese Weise werden
Fehlerpräsenter geschützt, um zu verhindern, dass sie von einer URL ausgelöst werden:
#[Requires(forward: true)]
class ForwardedPresenter extends Nette\Application\UI\Presenter
{
}
In der Praxis ist es oft notwendig, bestimmte Ansichten zu markieren, auf die nur aufgrund der Logik im Präsentator zugegriffen werden kann. Auch hier gilt, dass sie nicht direkt geöffnet werden können:
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
{
}
}
Spezifische Aktionen
Sie können auch einschränken, dass bestimmter Code, wie das Erstellen einer Komponente, nur für bestimmte Aktionen im Präsentator zugänglich ist:
class EditDeletePresenter extends Nette\Application\UI\Presenter
{
#[Requires(actions: ['add', 'edit'])]
public function createComponentPostForm()
{
}
}
Für eine einzelne Aktion muss kein Array geschrieben werden: #[Requires(actions: 'default')]
Benutzerdefinierte Attribute
Wenn Sie das Attribut #[Requires]
Attribut wiederholt mit denselben Einstellungen verwenden möchten, können Sie
ein eigenes Attribut erstellen, das die #[Requires]
erbt, und es nach Ihren Bedürfnissen einstellen.
Zum Beispiel, #[SingleAction]
erlaubt den Zugriff nur über die Aktion default
:
#[Attribute]
class SingleAction extends Nette\Application\Attributes\Requires
{
public function __construct()
{
parent::__construct(actions: 'default');
}
}
#[SingleAction]
class SingleActionPresenter extends Nette\Application\UI\Presenter
{
}
Oder #[RestMethods]
ermöglicht den Zugriff über alle für die REST-API verwendeten HTTP-Methoden:
#[\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
{
}
Schlussfolgerung
Das #[Requires]
Attribut gibt Ihnen große Flexibilität und Kontrolle darüber, wie auf Ihre Webseiten
zugegriffen wird. Mit einfachen, aber leistungsfähigen Regeln können Sie die Sicherheit und das ordnungsgemäße Funktionieren
Ihrer Anwendung verbessern. Wie Sie sehen, kann die Verwendung von Attributen in Nette Ihre Arbeit nicht nur vereinfachen, sondern
auch sichern.