Maison >développement back-end >Tutoriel Python >Utilisation de la protection CSRF avec les requêtes Django et AJAX

Utilisation de la protection CSRF avec les requêtes Django et AJAX

DDD
DDDoriginal
2025-01-07 18:15:39358parcourir

Using CSRF Protection with Django and AJAX Requests

Sécurisation des requêtes Django AJAX avec la protection CSRF

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é.

Configuration de l'application

Notre exemple d'application comporte deux points de terminaison :

  • GET /get-picture : Récupère l'URL d'une image stockée sur le serveur.
  • POST /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.

Activation de la protection CORS et CSRF

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.

Récupération et utilisation du jeton 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.

Modifier la requête POST

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.

Considérations importantes

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.

Ressources

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn