2010-11-27 18 views
5

django-registro que reciben este mensaje:"Falta el token CSRF persistente o incorrecto". Jinja y configuración

CSRF simbólico que falta o incorrecta.

En la mayoría de los foros, le pido que obtenga el {% csrf_token%} en el formulario, y lo tengo.

También tengo en mi settings.py:

TEMPLATE_CONTEXT_PROCESSORS = (
"django.contrib.auth.context_processors.csrf", 
"django.contrib.auth.context_processors.auth", 
) 

estoy usando jinja, lo que no parece utilizar CSRF, pero luego he instalado el registro Django y me he perdido, ya que, parece Usar otras vistas, a las que no tengo acceso, por decir que no están escritas por mí, y no puedo entender dónde están. "vistas de autenticación estándar" como las llaman. Entonces no puedo agregar "RequestContext".

¿Alguna idea de lo que está pasando y cómo puedo hacerlo funcionar? thanx

+0

¿Cómo es tu plantilla? – JonC

+0

{% extends "site_base.html" %} {% cuerpo de bloque%}

\t {% csrf_token%} {{form.as_p} }
{% cuerpo endblock%} – mgPePe

Respuesta

3

Es posible que deba volver a escribir la vista django-registration manualmente. Parece que hay un issue with how Jinja likes to do things and how Django wants to configure template loaders..

Para ver las vistas de autenticación estándar, solo busque en "paquetes de sitio" en su instalación de python.

Usted podría tratar de envolver los puntos de vista de autenticación estándar como esto:

from django.contrib.auth.views import login, logout 
from django.views.decorators.csrf import csrf_protect 

@csrf_protect 
def my_wrapped_login_view(request): 
    return login(request) 

@csrf_protect 
def my_wrapped_logout_view(request): 
    return logout(request) 

básicamente importado vistas de autenticación estándar de Django y los llamó con mi propia, que tiene la decoración csrf_protect. Vale la pena un tiro.

+0

Tu respuesta es un poco complicada, así que voy a tener que investigarla poco a poco, y sobre todo cómo configurar una vista personalizada. muchas gracias – mgPePe

2

¿También tiene instalado el sistema estándar de Django Templating? Eso será necesario para la mayoría de las aplicaciones que se distribuyen con plantillas.

Para CSRF, un procesador de contexto inserta la variable 'csrf_token' en el contexto de respuesta que recupera del middleware si está habilitado. Ahora todo lo que tiene que hacer es asegurarse de que sea parte de su formulario.

Esto es directamente de django.core, y está sujeto a cambios en cualquier momento.

 if csrf_token: 
      if csrf_token == 'NOTPROVIDED': 
       return mark_safe(u"") 
      else: 
       return mark_safe(u"<div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='%s' /></div>" % csrf_token) 

Sin embargo, al ver que, lo único que necesitas saber es que usted tiene que tener un tipo de entrada llamado csrfmiddlewaretoken con el valor de context.get ('csrf_token', '') dentro de su forma y eso es todo ella escribió.

+0

Estoy teniendo el mismo problema, ¿Qué sucede si no veo el tipo de entrada llamado csrfmiddlewaretoken cuando miro la fuente de la plantilla? – juankysmith

+0

@juanky, el punto es que debe incluirse en sus plantillas. django proporciona un procesador de contexto '{% csrf_token%}' para este propósito. Si usa un lenguaje de plantillas diferente, debe asegurarse de que el html en el código anterior esté incluido en todos y cada uno de los formularios de sus plantillas. –

+0

Tengo {% csrf_token%} dentro de cada formulario, mis vistas usan RequestContext en lugar de solicitud y TEMPLATE_CONTEXT_PROCESSORS se ordenan correctamente en settings.py ... pero sigo recibiendo este estúpido mensaje 'CSRF token missing or incorrect' – juankysmith

1

La respuesta más directa a esto es simplemente poner {% csrf_token%} dentro de la etiqueta de formulario en su plantilla/html.

-6

acabo apagó el middleware CSRF en la configuración como tal, y ahora funciona:

#'django.middleware.csrf.CsrfViewMiddleware', 
+2

Ahora tiene sin protección CSRF. ¡Esto * no * debe marcarse como la respuesta correcta! – spookylukey

+2

¡MAL MALO MALO MALO MALO MALO MALO! –

2

Esta respuesta no es específico de Django registro, pero sólo usando Django con Jinja2 en general.

CsrfViewMiddleware de Django establece la cookie csrf_token si determina que ha accedido al miembro de contexto csrf_token. Lamentablemente, la representación de Jinja2 no se produce hasta después de que se ejecuta el middleware de Django. Como resultado, la cookie no se establece y, por lo tanto, no coincide con el formulario, y obtendrá el error 403.

Para solucionar este problema, debe acceder al contexto ['csrf_token'] en algún momento antes de finalizar el procesamiento de la respuesta.

Si está utilizando puntos de vista basados ​​en la clase, se puede crear un CsrfProtectMixin:

class CsrfProtectMixin(object): 
    def render_to_response(self, context, **response_kwargs): 
     # Csrf processing happens when using a RequestContext. 
     # Be sure to use one. 
     if not isinstance(context, RequestContext): 
      context = RequestContext(self.request, context) 

     # Force access to csrf_token due to the way jinja2 renders the template 
     # after middleware has finished processing. Otherwise, the csrf cookie 
     # will not be set. 
     str(context.get('csrf_token')) 

     return super(CsrfProtectMixin, self).render_to_response(context, **response_kwargs) 

Y luego, en la clase de vista:

class MyView(CsrfProtectMixin, TemplateView): 
    def get(self, request, *args, **kwargs): 
     context = {} 
     return self.render_to_response(context) 

Si no se está usando basado en clases puntos de vista, se puede hacer algo como:

def my_view(request): 
    context = RequestContext(request) 
    str(context['csrf_token']) #force access to the csrf_token 
    return render_to_response('template.html', context) 

O quizás mono parche render_to_reponse con la lógica de la clase, encima.

Cuestiones relacionadas