Djangos integrierter CSRF-Schutz (Cross-Site Request Forgery), der beim Erstellen eines Projekts mit django-admin startproject
standardmäßig aktiviert ist, nutzt ein CSRF-Token zum Schutz vor böswilligen Anfragen. Diese Middleware wird zu Ihrem settings.py
.
Jede POST-Anfrage an Ihre Django-Anwendung erfordert ein gültiges CSRF-Token. In Django-Vorlagen wird dies erreicht, indem {% csrf_token %}
mithilfe der POST-Methode in jedes Formular eingefügt wird. Die Handhabung des CSRF-Schutzes mit separaten Front-End-AJAX-Anfragen erfordert jedoch einen anderen Ansatz.
Dieses Tutorial zeigt die Sicherung einer einfachen Django-Anwendung mit AJAX-Anfragen von einem separaten Frontend.
Unsere Beispielanwendung verfügt über zwei Endpunkte:
/get-picture
: Ruft die URL eines auf dem Server gespeicherten Bildes ab./set-picture
: Aktualisiert die URL des auf dem Server gespeicherten Bildes.Der Einfachheit halber wird auf die Fehlerbehandlung verzichtet. Der anfängliche Backend-Code (in urls.py
) lautet wie folgt:
<code class="language-python">from django.urls import path from django.http import JsonResponse import json picture_url = "https://picsum.photos/id/247/720/405" def get_picture(request): return JsonResponse({"picture_url": picture_url}) def set_picture(request): if request.method == "POST": global picture_url picture_url = json.loads(request.body)["picture_url"] return JsonResponse({"picture_url": picture_url}) urlpatterns = [ path("get-picture", get_picture), path("set-picture", set_picture) ]</code>
Die entsprechenden Frontend-Funktionen (vereinfacht):
<code class="language-javascript">// GET request to retrieve the image URL async function get_picture() { const res = await fetch("http://localhost:8000/get-picture"); const data = await res.json(); return data.picture_url; } // POST request to update the image URL async function set_picture(picture_url) { const res = await fetch("http://localhost:8000/set-picture", { method: "POST", body: JSON.stringify({ "picture_url": picture_url }) }); }</code>
Um Cross-Origin Resource Sharing (CORS) zu handhaben, verwenden wir das django-cors-headers
-Paket.
Installieren django-cors-headers
:
<code class="language-bash">pip install django-cors-headers</code>
Konfigurieren settings.py
:
<code class="language-python">INSTALLED_APPS = [ "corsheaders", # ... other apps ] MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", # ... other middleware ] CORS_ALLOWED_ORIGINS = ["http://localhost:4040"] # Adjust port as needed CSRF_TRUSTED_ORIGINS = ["http://localhost:4040"] # Add your frontend origin</code>
Während GET-Anfragen jetzt ordnungsgemäß funktionieren, schlagen POST-Anfragen aufgrund des CSRF-Schutzes fehl. Um dieses Problem zu beheben, müssen wir CSRF-Tokens manuell verwalten.
Erstellen Sie eine neue Ansicht, um das CSRF-Token bereitzustellen:
<code class="language-python">from django.views.decorators.csrf import ensure_csrf_cookie from django.http import JsonResponse @ensure_csrf_cookie def get_csrf_token(request): return JsonResponse({"success": True}) urlpatterns = [ # ... other paths path("get-csrf-token", get_csrf_token), ]</code>
Aktualisieren Sie das Frontend, um das Token abzurufen (mit js-cookie
):
<code class="language-javascript">fetch("http://localhost:8000/get-csrf-token", { credentials: "include" });</code>
Die Option credentials: "include"
stellt sicher, dass der Browser alle Set-Cookie
-Header verarbeitet und das csrftoken
-Cookie speichert. Überprüfen Sie die Registerkarte „Netzwerk“ in den Entwicklertools Ihres Browsers, um sicherzustellen, dass das Cookie gesetzt ist.
Ändern Sie abschließend die Funktion set_picture
, um das CSRF-Token in den Header aufzunehmen:
<code class="language-javascript">async function set_picture(picture_url) { const res = await fetch("http://localhost:8000/set-picture", { method: "POST", credentials: "include", headers: { 'X-CSRFToken': Cookies.get("csrftoken") }, body: JSON.stringify({ "picture_url": picture_url }) }); }</code>
Dadurch wird der X-CSRFToken
-Header mit dem Wert aus dem csrftoken
-Cookie hinzugefügt und ermöglicht so erfolgreiche POST-Anfragen.
Dieser Ansatz weist Einschränkungen auf, insbesondere wenn das Front-End und das Back-End auf unterschiedlichen Domänen bereitgestellt werden. Browser-Sicherheitsrichtlinien verhindern möglicherweise das Setzen oder Zugreifen auf Cookies von Drittanbietern, was sich auf die CSRF-Token-Verwaltung auswirkt.
Das obige ist der detaillierte Inhalt vonVerwenden des CSRF-Schutzes mit Django- und AJAX-Anfragen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!