Como desabilitar a validação CSRF do Django?

111

Comentei as linhas de processador csrf e middleware em 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 )

Mas quando eu uso Ajax para enviar uma solicitação, o Django ainda responde 'token csrf está incorreto ou ausente', e depois de adicionar X-CSRFToken aos cabeçalhos, a solicitação seria bem-sucedida.

O que está acontecendo aqui ?

WoooHaaaa
fonte
Possível duplicata: stackoverflow.com/questions/1650941/…
Rohan

Respostas:

232

Se você só precisa de algumas visualizações para não usar o CSRF, pode usar @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

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

Você pode encontrar mais exemplos e outros cenários na documentação do Django:

Salvatorelab
fonte
2
Olá, @TheBronx, realmente quero saber por que minha solução não funciona.
WoooHaaaa
1
desculpe @MrROY Não sei por que sua solução não está funcionando. Só sei que @csrf_exempfunciona como usei recentemente sem problemas. Espero que você encontre a resposta.
Salvatorelab
6
@MrROY, É uma coisa do Django. A maioria das coisas funciona / não funciona apenas porque há uma configuração mágica enterrada profundamente na base do código.
idursun 01 de
2
Um lembrete: se você tiver outros decoradores na mesma visualização, a ordem é relevante: coloque @csrf_exempt primeiro.
Patrick Bassut
3
Hmm- talvez uma resposta tecnicamente correta, mas certamente não o que o OP queria ou o que eu estava procurando.
Danny Staple
40

Para desabilitar CSRF para visualizações baseadas em classe, o seguinte funcionou para mim.
Usando django 1.10 e 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
fonte
32

No setting.pyMIDDLEWARE você pode simplesmente remover / comentar esta linha:

'django.middleware.csrf.CsrfViewMiddleware',
Rohit33
fonte
1
isso funciona para mim no Django 2.1 usando curl como um cliente http.
argila
1
@xtrinch Certifique-se de encerrar / reiniciar totalmente o processo do servidor. Eu não acho que o relaod automático capta a mudança
Básico,
15

Para Django 2 :

from django.utils.deprecation import MiddlewareMixin


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

Esse middleware deve ser adicionado settings.MIDDLEWAREquando apropriado (nas configurações de teste, por exemplo).

Nota: a configuração não é MIDDLEWARE_CLASSESmais chamada .

François Constant
fonte
11

A resposta pode ser inadequada, mas espero que ajude você

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

Ter um middleware como esse ajuda a depurar solicitações e verificar o csrf em servidores de produção.

Naren
fonte
Hmm. Tentei isso no Django 1.9.1. Removido o decorador @csrf_exempt do método e adicionado o código acima. Recebi um 403 porque o cookie não foi definido.
Craig S. Anderson
11

O problema aqui é que SessionAuthentication executa sua própria validação CSRF. É por isso que você obtém o erro CSRF missing mesmo quando o CSRF Middleware é comentado. Você poderia adicionar @csrf_exempt a cada visão, mas se quiser desabilitar o CSRF e ter autenticação de sessão para todo o aplicativo, você pode adicionar um middleware extra como este -

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

Eu criei esta classe em myapp / middle.py Em seguida, importe este middleware no Middleware em 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',

]

Isso funciona com DRF no django 1.11

Madhuri Gole
fonte
3
Obrigado por realmente dar uma resposta à pergunta em vez de apenas postar uma solução.
ThaJay
5

Se você quiser desabilitá-lo no Global, você pode escrever um middleware personalizado, como este

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)

em seguida, adicione esta classe youappname.middlewarefilename.DisableCsrfCheckàs MIDDLEWARE_CLASSESlistas, antesdjango.middleware.csrf.CsrfViewMiddleware

JJP
fonte
0

@WoooHaaaa alguns pacotes de terceiros usam o middleware 'django.middleware.csrf.CsrfViewMiddleware'. por exemplo, eu uso django-rest-oauth e tenho problemas como você mesmo depois de desabilitar essas coisas. talvez esses pacotes tenham respondido ao seu pedido como o meu caso, porque você usa decorador de autenticação e algo assim.

M.qaemi Qaemi
fonte