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 ?

WoooHaaaa
la source

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:

Salvatorelab
la source
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')
Martijn ten Hoor
la source
32

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

'django.middleware.csrf.CsrfViewMiddleware',
Rohit33
la source
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.

François Constant
la source
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.

Naren
la source
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

Madhuri Gole
la source
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

JJP
la source
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.

M.qaemi Qaemi
la source