¿Cómo deshabilitar la validación CSRF de Django?


111

He comentado el procesador csrf y las líneas de middleware en 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 )

Pero cuando uso Ajax para enviar una solicitud, Django todavía responde 'el token csrf es incorrecto o falta', y después de agregar X-CSRFToken a los encabezados, la solicitud se realizará correctamente.

Que esta pasando aqui ?


Respuestas:


232

Si solo necesita algunas vistas para no usar CSRF, puede usar @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

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

Puede encontrar más ejemplos y otros escenarios en la documentación de Django:


2
Hola, @TheBronx, realmente quiero saber por qué mi solución no funciona.
WoooHaaaa

1
Lo siento @MrROY No sé por qué su solución no funciona. Solo sé que @csrf_exempfunciona ya que lo he usado recientemente sin problemas. Espero que encuentres la respuesta.
Salvatorelab

6
@MrROY, es una cosa de Django. La mayoría de las cosas funcionan / no funcionan solo porque hay una configuración mágica enterrada en el fondo del código.
idursun

2
Un recordatorio: si tiene otros decoradores en la misma vista, el orden es relevante: coloque primero @csrf_exempt.
Patrick Bassut

3
Hmm, tal vez una respuesta técnicamente correcta, pero ciertamente no es lo que quería el OP o lo que estaba buscando.
Danny Staple

40

Para deshabilitar CSRF para vistas basadas en clases, lo siguiente funcionó para mí.
Usando django 1.10 y 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

En setting.pyMIDDLEWARE, simplemente puede eliminar / comentar esta línea:

'django.middleware.csrf.CsrfViewMiddleware',

1
esto funciona para mí en Django 2.1 usando curl como cliente http.
arcilla

1
@xtrinch Asegúrese de cerrar / reiniciar completamente el proceso del servidor. No creo que el auto-relaod recoja el cambio
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)

Ese middleware debe agregarse settings.MIDDLEWAREcuando sea apropiado (en su configuración de prueba, por ejemplo).

Nota: la configuración ya no se llama MIDDLEWARE_CLASSES.


11

La respuesta puede ser inapropiada, pero espero que te ayude

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

Tener un middleware como este ayuda a depurar solicitudes y verificar csrf en servidores de producción.


Hmm. Probé esto en Django 1.9.1. Se eliminó el decorador @csrf_exempt del método y se agregó el código anterior. Obtuve un 403 porque la cookie no estaba configurada.
Craig S. Anderson

11

El problema aquí es que SessionAuthentication realiza su propia validación CSRF. Es por eso que obtiene el error de falta de CSRF incluso cuando se comenta el Middleware de CSRF. Puede agregar @csrf_exempt a cada vista, pero si desea deshabilitar CSRF y tener autenticación de sesión para toda la aplicación, puede agregar un middleware adicional 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

Creé esta clase en myapp / middle.py Luego importe este middleware en Middleware en 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',

]

Eso funciona con DRF en django 1.11


3
Gracias por dar una respuesta a la pregunta en lugar de publicar una solución.
ThaJay

5

Si desea deshabilitarlo en Global, puede escribir un 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)

luego agregue esta clase youappname.middlewarefilename.DisableCsrfChecka las MIDDLEWARE_CLASSESlistas, antesdjango.middleware.csrf.CsrfViewMiddleware



0

@WoooHaaaa algunos paquetes de terceros utilizan el middleware 'django.middleware.csrf.CsrfViewMiddleware'. por ejemplo, uso django-rest-oauth y tengo un problema como tú incluso después de deshabilitar esas cosas. tal vez estos paquetes respondieron a su solicitud como mi caso, porque usa decorador de autenticación y algo así.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.