2010-09-21 8 views
10

Recientemente me actualicé a Django 1.2.3 y mis formularios de carga ahora están rotos. Cada vez que intento cargar, recibo una "verificación de CSRF fallida. Solicitud cancelada". mensaje de error.¿Cómo incluyo el token CSRF de Django 1.2 en un formulario HTML generado por Javascript?

Después de leer Django's documentation sobre este tema, indica que debo agregar la etiqueta de plantilla {% csrf_token%} dentro del HTML <form> en mi plantilla. Desafortunadamente, mi <form> se genera a través de JavaScript (específicamente, la propiedad "html" de ExtJs en un Panel).

En resumen, ¿cómo agrego la etiqueta de token CSRF requerida a mi <form> cuando mi <form> no está incluido en una plantilla de Django?

Respuesta

13

Otra opción sería adaptar la solución basada en cookie/encabezado que se muestra en the Django docs con Ext, preferiblemente si tiene muchas plantillas y no desea cambiar todas y cada una de ellas.

tan sólo reduce el siguiente fragmento en sus overrides.js (o donde pones modificaciones globales):

Ext.Ajax.on('beforerequest', function (conn, options) { 
    if (!(/^http:.*/.test(options.url) || /^https:.*/.test(options.url))) { 
    if (typeof(options.headers) == "undefined") { 
     options.headers = {'X-CSRFToken': Ext.util.Cookies.get('csrftoken')}; 
    } else { 
     options.headers.extend({'X-CSRFToken': Ext.util.Cookies.get('csrftoken')}); 
    }       
    } 
}, this); 

(edit: Ext ya cuenta con función de lectura de cookies, no hay necesidad de duplicarlo)

+0

¿Debo hacer/agregar algo a mi formulario generado dinámicamente? – john2x

+1

@ john2x: No, solo necesitas poner el código en tus overrides.js. Si no está familiarizado con el concepto de overrides.js, el siguiente blog es un buen comienzo: http://edspencer.net/2009/07/extoverride-monkey-patching-ext-js.html – chrisv

+0

+1. ¡Genial, estaba pensando en la misma línea cuando encontré esta respuesta! – Swanand

9

La manera más fácil es crear un formulario oculto en su página usando django que no hace nada. Luego use JavaScript para obtener el formulario y específicamente la entrada del token fuera del formulario. Por último, inserte o copie esa entrada de token en el formulario que está generando dinámicamente.

Aquí hay dos ejemplos de cómo puede publicar el token para JavaScript.

<input id="csrf_token" value="{{ csrf_token }}"/> 

<script type="text/javascript"> 
var CSRF_TOKEN = document.getElementById('csrf_token').value; 
</script> 

o

<script type="text/javascript"> 
var CSRF_TOKEN = "{{ csrf_token }}"; 
</script> 
+0

¿Puede dar un ejemplo? – Huuuze

+0

¿Por qué votar abajo? –

+0

@Huuuze: ponga '{csrf_token}' en la plantilla en algún lugar, y analícelo con JavaScript durante la creación del formulario. –

0

¿Tiene la vista en que se POST ing para responder también a GET? En que el código JS puede hacer una solicitud GET a la vista en cuestión y analizar el resultado para extraer el token CSRF. Mi JS-fu es débil y no estoy seguro de cuál es la mejor forma de analizar el análisis desde el lado del cliente.

Para una ampliamente ejemplo relacionado ver this question. En este caso, el usuario estaba intentando POST usando un script de Python y fallando por la misma razón. La solución era la misma, excepto que tenía que hacerlo desde un script de Python en lugar de JavaScript.

1

Una mejor solución es generar el código del archivo js desde una vista/plantilla.

A continuación, en la vista se puede establecer el csrf símbolo en el contexto así ...

from django.core.context_processors import csrf 
context = RequestContext(request) 
context.update(csrf(request)) 

A continuación, en la plantilla, puede utilizar {{ csrf_token }} para obtener el valor bruto del token CSRF , y luego usar eso para construir un campo oculto en su formulario con el nombre csrfmiddlewaretoken.

0

Esto puede no ser ideal, pero fue la solución más rápida para mí. En mi plantilla principal en la parte inferior del "cuerpo", agregué una función de JavaScript a mi biblioteca.

<script type="text/javascript"> 
    MyToolkit.Utils.getCSRFToken = function() { 
     return "{% csrf_token %}"; 
    }; 
</script> 
+0

Esa etiqueta devuelve un div oculto. Creo que querías decir {{csrf_token}} – Tom

0

Esto usará el token csrf o generar automáticamente uno nuevo si es necesario. Manejará todos los envíos de formularios en la página. Si tiene formularios fuera del sitio, deberá asegurarse de que no ejecuten este código.

<script> 
$(document).on('submit', 'form[method=post]', function(){ 
    if(!document.cookie.match('csrftoken=([a-zA-Z0-9]{32})')) { 
    for(var c = ''; c.length < 32;) c += 'abcdefghijklmnopqrstuvwxyz'.charAt(Math.random() * 26) 
    document.cookie = 'csrftoken=' + c + '; path=/' 
    } 
    if(!this.csrfmiddlewaretoken) $(this).append('<input type="hidden" name="csrfmiddlewaretoken">') 
    $(this.csrfmiddlewaretoken).val(document.cookie.match('csrftoken=([a-zA-Z0-9]{32})')[1]) 
}) 
</script> 

requiere jQuery 1.7+

Cuestiones relacionadas