Comment désactiver la validation CSRF de Django?


111

J'ai commenté le processeur csrf et les lignes middleware dans settings.py:

122 
123 TEMPLATE_CONTEXT_PROCESSORS = (
124     'django.contrib.auth.context_processors.auth',
125 #    'django.core.context_processors.csrf',
126     'django.core.context_processors.request',
127     'django.core.context_processors.static',
128     'cyathea.processors.static',
129 )
130 
131 MIDDLEWARE_CLASSES = (
132     'django.middleware.common.CommonMiddleware',
133     'django.contrib.sessions.middleware.SessionMiddleware',
134 #    'django.middleware.csrf.CsrfViewMiddleware',
135     'django.contrib.auth.middleware.AuthenticationMiddleware',
136     'django.contrib.messages.middleware.MessageMiddleware',
137     'django.middleware.locale.LocaleMiddleware',
138     # Uncomment the next line for simple clickjacking protection:
139     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
140 )

Mais lorsque j'utilise Ajax pour envoyer une requête, Django répond toujours «le jeton csrf est incorrect ou manquant», et après avoir ajouté X-CSRFToken aux en-têtes, la requête réussit.

Qu'est-ce qui se passe ici ?


Réponses:


232

Si vous avez juste besoin de quelques vues pour ne pas utiliser CSRF, vous pouvez utiliser @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

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

Vous pouvez trouver plus d'exemples et d'autres scénarios dans la documentation Django:


2
Salut, @TheBronx, je veux vraiment savoir pourquoi ma solution ne fonctionne pas.
WoooHaaaa

1
désolé @MrROY Je ne sais pas pourquoi votre solution ne fonctionne pas. Je sais juste que cela @csrf_exempfonctionne comme je l'ai utilisé récemment sans problème. J'espère que vous trouverez la réponse.
Salvatorelab

6
@MrROY, c'est un truc Django. La plupart des choses fonctionnent / ne fonctionnent pas simplement parce qu'il y a un paramètre magique enfoui au plus profond de la base du code.
idursun

2
Un rappel: si vous avez d'autres décorateurs dans la même vue, l'ordre est pertinent: placez donc @csrf_exempt en premier.
Patrick Bassut

3
Hmm- peut-être une réponse techniquement correcte, mais certainement pas ce que l'OP voulait ou ce que je cherchais.
Danny Staple

40

Pour désactiver CSRF pour les vues basées sur les classes, ce qui suit a fonctionné pour moi.
Utiliser django 1.10 et python 3.5.2

from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
    def post(self, request, *args, **kwargs):
        return HttpResponse('Hello world')

32

Dans setting.pyMIDDLEWARE, vous pouvez simplement supprimer / commenter cette ligne:

'django.middleware.csrf.CsrfViewMiddleware',

1
cela fonctionne pour moi sur Django 2.1 en utilisant curl comme client http.
terre battue

1
@xtrinch Assurez-vous de quitter / relancer complètement le processus serveur. Je ne pense pas que la relaod automatique ramasse le changement
base

15

Pour Django 2 :

from django.utils.deprecation import MiddlewareMixin


class DisableCSRF(MiddlewareMixin):
    def process_request(self, request):
        setattr(request, '_dont_enforce_csrf_checks', True)

Ce middleware doit être ajouté le settings.MIDDLEWAREcas échéant (dans vos paramètres de test par exemple).

Remarque: le paramètre n'est plus appelé MIDDLEWARE_CLASSES.


11

La réponse peut être inappropriée, mais j'espère que cela vous aidera

class DisableCSRFOnDebug(object):
    def process_request(self, request):
        if settings.DEBUG:
            setattr(request, '_dont_enforce_csrf_checks', True)

Avoir un middleware comme celui-ci permet de déboguer les requêtes et de vérifier csrf dans les serveurs de production.


Hmm. J'ai essayé cela dans Django 1.9.1. Suppression du décorateur @csrf_exempt de la méthode et ajout du code ci-dessus. Vous avez un 403 car le cookie n'a pas été défini.
Craig

11

Le problème ici est que SessionAuthentication effectue sa propre validation CSRF. C'est pourquoi vous obtenez l'erreur manquante CSRF même lorsque le middleware CSRF est commenté. Vous pouvez ajouter @csrf_exempt à chaque vue, mais si vous souhaitez désactiver CSRF et disposer d'une authentification de session pour l'ensemble de l'application, vous pouvez ajouter un middleware supplémentaire comme celui-ci -

class DisableCSRFMiddleware(object):

def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request):
    setattr(request, '_dont_enforce_csrf_checks', True)
    response = self.get_response(request)
    return response

J'ai créé cette classe dans myapp / middle.py Puis importez ce middleware dans Middleware dans settings.py

MIDDLEWARE = [
    'django.middleware.common.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'myapp.middle.DisableCSRFMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

Cela fonctionne avec DRF sur django 1.11


3
Merci de donner une réponse à la question au lieu de simplement publier une solution.
ThaJay

5

Si vous souhaitez le désactiver dans Global, vous pouvez écrire un middleware personnalisé, comme celui-ci

from django.utils.deprecation import MiddlewareMixin

class DisableCsrfCheck(MiddlewareMixin):

    def process_request(self, req):
        attr = '_dont_enforce_csrf_checks'
        if not getattr(req, attr, False):
            setattr(req, attr, True)

puis ajoutez cette classe youappname.middlewarefilename.DisableCsrfCheckaux MIDDLEWARE_CLASSESlistes, avantdjango.middleware.csrf.CsrfViewMiddleware



0

@WoooHaaaa certains packages tiers utilisent le middleware 'django.middleware.csrf.CsrfViewMiddleware'. par exemple, j'utilise django-rest-oauth et j'ai un problème comme toi même après avoir désactivé ces choses. peut-être que ces paquets ont répondu à votre demande comme mon cas, car vous utilisez un décorateur d'authentification et quelque chose comme ça.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.