2012-07-07 21 views
22

Estoy intentando escribir un sitio en Django en el que las URL de API son las mismas que las URL de usuario. Pero tengo problemas con páginas que usan solicitudes POST y protección CSRF. Por ejemplo, si tengo una página/foo/agregar Quiero ser capaz de enviar solicitudes POST a ella de dos maneras:¿Cómo puedo desactivar la protección csrf de Django solo en ciertos casos?

  1. Como usuario final (autenticado utilizando una cookie de sesión) enviar un formulario. Esto requiere protección CSRF.
  2. Como cliente API (autenticado usando un encabezado de solicitud HTTP). Esto fallará si la protección CSRF está habilitada.

He encontrado varias formas de deshabilitar CSRF, como @csrf_exempt, pero todas ellas lo deshabilitan para toda la vista. ¿Hay alguna forma de habilitarlo/deshabilitarlo a un nivel más detallado? ¿O voy a tener que implementar por propia protección CSRF desde cero?

+1

¿Marcó [csrf protection docs] (https://docs.djangoproject.com/en/dev/ref/contrib/csrf/)? – machaku

+0

Había leído partes de él, pero claramente no leí todos los Escenarios. ¡Gracias! – lucas

Respuesta

22

Hay una sección de la documentación de protección CSRF de Django titulada View needs protection for one path que describe una solución. La idea es usar @csrf_exempt en toda la vista, pero cuando el encabezado del cliente API no está presente o no es válido, llame a una función anotada con @csrf_protect.

30

Modificar urls.py

Si usted maneja sus rutas en urls.py, se puede envolver sus rutas deseadas con csrf_exempt() para excluirlos de la verificación de middleware CSRF.

por ejemplo,

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())) 
    # ... 
) 

Alternativamente, como decorador

Algunos pueden encontrar el uso de la @csrf_exempt decorador más adecuado para sus necesidades

por ejemplo,

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

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