Maison >développement back-end >Tutoriel Python >Utilisation de la protection CSRF avec les requêtes Django et AJAX
La protection CSRF (Cross-Site Request Forgery) intégrée de Django, activée par défaut lors de la création d'un projet avec django-admin startproject
, utilise un jeton CSRF pour se protéger contre les requêtes malveillantes. Ce middleware est ajouté à votre settings.py
.
Chaque requête POST adressée à votre application Django nécessite un jeton CSRF valide. Dans les modèles Django, ceci est réalisé en incluant {% csrf_token %}
dans n'importe quel formulaire en utilisant la méthode POST. Cependant, la gestion de la protection CSRF avec des requêtes AJAX frontales distinctes nécessite une approche différente.
Ce tutoriel montre comment sécuriser une application Django simple avec des requêtes AJAX provenant d'un front-end séparé.
Notre exemple d'application comporte deux points de terminaison :
/get-picture
: Récupère l'URL d'une image stockée sur le serveur./set-picture
: Met à jour l'URL de l'image stockée sur le serveur.Pour plus de simplicité, la gestion des erreurs est omise. Le code backend initial (dans urls.py
) est le suivant :
<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>
Les fonctions front-end correspondantes (simplifiées) :
<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>
Pour gérer le partage de ressources cross-origine (CORS), nous utiliserons le package django-cors-headers
.
Installer django-cors-headers
:
<code class="language-bash">pip install django-cors-headers</code>
Configurer 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>
Bien que les requêtes GET fonctionnent désormais correctement, les requêtes POST échoueront en raison de la protection CSRF. Pour résoudre ce problème, nous devons gérer manuellement les jetons CSRF.
Créez une nouvelle vue pour servir le jeton CSRF :
<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>
Mettez à jour le front-end pour récupérer le jeton (en utilisant js-cookie
) :
<code class="language-javascript">fetch("http://localhost:8000/get-csrf-token", { credentials: "include" });</code>
L'option credentials: "include"
garantit que le navigateur gère tous les en-têtes Set-Cookie
, en stockant le cookie csrftoken
. Inspectez l'onglet Réseau dans les outils de développement de votre navigateur pour vérifier que le cookie est défini.
Enfin, modifiez la fonction set_picture
pour inclure le token CSRF dans l'en-tête :
<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>
Cela ajoute l'en-tête X-CSRFToken
avec la valeur du cookie csrftoken
, permettant ainsi les requêtes POST réussies.
Cette approche présente des limites, notamment lors du déploiement du front-end et du back-end sur des domaines différents. Les politiques de sécurité du navigateur peuvent empêcher la configuration ou l'accès à des cookies tiers, ce qui a un impact sur la gestion des jetons CSRF.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!