web-dev-qa-db-fra.com

Comment puis-je désactiver la protection csrf de Django uniquement dans certains cas?

J'essaie d'écrire un site dans Django où les URL d'API sont les mêmes que les URL accessibles aux utilisateurs. Mais je rencontre des problèmes avec les pages qui utilisent les requêtes POST et la protection CSRF. Par exemple, si j'ai une page/foo/add, je veux pouvoir lui envoyer POST requêtes de deux manières:

  1. En tant qu'utilisateur final (authentifié à l'aide d'un cookie de session) soumettant un formulaire. Cela nécessite une protection CSRF.
  2. En tant que client API (authentifié à l'aide d'un en-tête de requête HTTP). Cela échouera si la protection CSRF est activée.

J'ai trouvé différentes façons de désactiver CSRF, telles que @csrf_exempt, mais elles le désactivent toutes pour la vue entière. Existe-t-il un moyen de l'activer/le désactiver à un niveau plus fin? Ou vais-je simplement devoir implémenter par moi-même une protection CSRF?

32
lucas

Il existe une section de la documentation de Django sur la protection CSRF intitulée View a besoin d'une protection pour un chemin qui décrit une solution. L'idée est d'utiliser @csrf_exempt sur l'ensemble de la vue, mais lorsque l'en-tête du client API n'est pas présent ou non valide, appelez alors une fonction annotée avec @csrf_protect.

27
Daniel Trebbien

Modifier urls.py

Si vous gérez vos itinéraires dans urls.py, Vous pouvez envelopper vos itinéraires souhaités avec csrf_exempt() pour les exclure du middleware de vérification CSRF.

par exemple,

from Django.views.decorators.csrf import csrf_exempt
urlpatterns = patterns(
    # ...
    # Will exclude `/api/v1/test` from CSRF 
    url(r'^api/v1/test', csrf_exempt(TestApiHandler.as_view()))
    # ...
)

Alternativement, en tant que décorateur

Pour certains, l'utilisation du décorateur @csrf_exempt Convient mieux à leurs besoins

par exemple,

from Django.views.decorators.csrf import csrf_exempt
from Django.http import HttpResponse

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')
51
Jossef Harush

Si vous utilisez la vue de base de classe (CBV) et que vous souhaitez utiliser le décorateur csrf_exempt, vous devrez utiliser le décorateur de méthode.

from Django.utils.decorators import method_decorator
from Django.views import View
from Django.views.decorators.csrf import csrf_exempt

@method_decorator(csrf_exempt, name='dispatch')
class MyView(View):
    def post(self, request):
        pass  # my view code here
0
Thomas Turner