2011-03-31 14 views
6

De acuerdo con la documentación de django, para la solicitud de ajax en 1.3 (al menos con Jquery), solo necesitamos agregar este snippet al archivo js principal. Este fragmento obtiene csrftoken de las cookies y luego lo configura para todas las solicitudes ajax. Eso es trabajo, pero ¿y si csrftoken no existe en las cookies? Pensé render_to_response y render ambos automáticamente comprueba si csrftoken en sesiones, y lo configuramos para nosotros, si el token no está allí. Pero no lo son. Entonces, ¿debo implementarlo solo? O tal vez hay otra manera de manejar la protección ajax csrf?Problema de Ajax CSRF en Django 1.3

Respuesta

3

Su cookie sólo contiene el token CSRF, si se utilizó o bien la etiqueta de plantilla {% csrf_token %} en la plantilla para generar la solicitud, o si se llama get_token (con el objeto request como argumento) de django.middleware.csrf.

La función get_token establece metainformación sobre el objeto request que a su vez le dice al middleware django.middleware.csrf.CsrfViewMiddleware para establecer la cookie.

3

En cuanto a Ajax, debe pasar el token csrf con cada solicitud. Para jQuery, utilizo el siguiente código:

$.ajaxPrefilter(function(options, originalOptions, jqXHR) { 
    if(!options.crossDomain) { 
     if(options.data) { 
      options.data += "&"; 
     } else { 
      options.data = ""; 
     } 
     options.data += "csrfmiddlewaretoken={{csrf_token}}"; 
    } 
}); 
11

Cuando no hay un formulario en una página que ya está usando {%} csrf_token%, no se enviará la cookie. Por lo tanto, como ha notado, obtendrá un error cuando intente utilizar Ajax en dicha página. Esto conducirá a un comportamiento errático si tiene un sitio con una combinación de páginas con varias combinaciones de formularios y publicaciones ajax.

Esto ya se ha informado y corregido: https://code.djangoproject.com/ticket/15354

La solución en el parche, se debe estirar con 1.3.1, es el decorador ensure_cookie_csrf. Ese decorador no existe en 1.3 o 1.2.5

No hay necesidad de esperar, sin embargo. Sólo tiene que añadir esta línea a cualquier punto de vista que contiene mensajes AJAX una forma CSRF:

request.META["CSRF_COOKIE_USED"] = True 

Ejemplo:

def calculator(request): 
    request.META["CSRF_COOKIE_USED"] = True 
    return render_to_response('calc.html', {'form': CalcForm()}) 

FYI - esto es exactamente lo que hace que el decorador.

+0

Según [documentación de CSRF Django] (https: // docs.djangoproject.com/en/dev/ref/contrib/csrf/#django.views.decorators.csrf.ensure_csrf_cookie), el decorador ensure_cookie_csrf es nuevo para Django 1.4. –

+1

Sí, el decorador ensure_csrf_cookie aterrizó en Django 1.4. Desafortunadamente no en 1.3.1 – bjunix

1

Una forma que he encontrado para evitar esto es mediante el uso de una forma preexistente como punto de partida para sus datos AJAX.

<form id="ajax_form" stye="display: none;">{% csrf_token %}</form> 

entonces usted puede utilizar esto en su código JavaScript a través de la función Serialize JQuery:

var data = $('#ajax_form').serialize(); 
data += "&mydata=69"; 

Incluso puede utilizar campos ocultos dentro de esa forma oculta de modo que usted no tiene que utilizar la concatenación de cadenas para construir tus datos POST.

1

Si está utilizando el decorador @csrf_protect, asegúrese de que tanto la vista con el formulario como la vista de los datos se publiquen para usar el decorador.

Tuve un problema similar. Solo tuve @csrf_protect en la vista de publicación que funcionó bien para probar localmente, pero cuando entré o obtuve un error de verificación 403 añadiendo el decorador a la vista de página fijada en