Wie man POST-Links richtig verwendet
In Webanwendungen, insbesondere in Verwaltungsschnittstellen, sollte es eine Grundregel sein, dass Aktionen, die den Zustand des Servers verändern, nicht über die HTTP-GET-Methode durchgeführt werden sollten. Wie der Name der Methode schon sagt, sollte GET nur zum Abrufen von Daten verwendet werden, nicht zum Ändern. Für Aktionen wie das Löschen von Datensätzen ist es angemessener, die POST-Methode zu verwenden. Ideal wäre die Verwendung der DELETE-Methode, die jedoch ohne JavaScript nicht aufgerufen werden kann, weshalb in der Regel POST verwendet wird.
Wie macht man das in der Praxis? Verwenden Sie diesen einfachen Trick. Erstellen Sie am Anfang Ihrer Vorlage ein Hilfsformular
mit dem Bezeichner postForm
, das Sie dann für die Schaltflächen zum Löschen verwenden werden:
<form method="post" id="postForm"></form>
Mit diesem Formular können Sie ein <button>
anstelle des klassischen <a>
Link verwenden,
der visuell so verändert werden kann, dass er wie ein normaler Link aussieht. Das Bootstrap-CSS-Framework bietet zum Beispiel die
Klassen btn btn-link
an, mit denen die Schaltfläche optisch nicht von anderen Links zu unterscheiden ist. Mit dem
Attribut form="postForm"
verknüpfen wir sie mit dem vorbereiteten Formular:
<table>
<tr n:foreach="$posts as $post">
<td>{$post->title}</td>
<td>
<button class="btn btn-link" form="postForm" formaction="{link delete $post->id}">delete</button>
<!-- instead of <a n:href="delete $post->id">delete</a> -->
</td>
</tr>
</table>
Beim Anklicken des Links wird nun die Aktion delete
aufgerufen. Um sicherzustellen, dass Anfragen nur über die
POST-Methode und von der gleichen Domäne akzeptiert werden (was ein wirksamer Schutz gegen CSRF-Angriffe ist), verwenden Sie das
#[Requires]
Attribut:
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); // hypothetical code for deleting a record
$this->redirect('default');
}
}
Das Attribut ist seit Nette Application 3.2 verfügbar, und Sie können mehr über seine Möglichkeiten auf der Seite How to use the #Requires attribute erfahren.
Wenn Sie das Signal handleDelete()
anstelle der Aktion actionDelete()
verwenden, ist es nicht
notwendig, sameOrigin: true
anzugeben, da Signale diesen Schutz implizit gesetzt haben:
#[Requires(methods: 'POST')]
public function handleDelete(int $id): void
{
$this->facade->deletePost($id);
$this->redirect('this');
}
Dieser Ansatz verbessert nicht nur die Sicherheit Ihrer Anwendung, sondern trägt auch zur Einhaltung der richtigen Webstandards und -praktiken bei. Durch die Verwendung von POST-Methoden für zustandsändernde Aktionen erreichen Sie eine robustere und sicherere Anwendung.