2010-11-27 32 views
5

Je reçois ce message:"Jeton CSRF persistant manquant ou incorrect". Jinja et configuration django-inscription

CSRF jeton de manquant ou incorrect.

Dans la plupart des forums, vous devez indiquer le {% csrf_token%} dans le formulaire, et je l'ai.

j'ai aussi dans mon settings.py:

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

J'utilise Jinja, qui ne semble pas utiliser CSRF, mais je l'ai installé l'enregistrement de django et je me suis perdu, depuis, il semble utiliser d'autres points de vue, auxquels je n'ai pas accès pour ainsi dire, ils ne sont pas écrits par moi, et je ne peux pas savoir où ils sont. "vues d'authentification standard" comme ils les appellent. Donc, je suis incapable d'ajouter "RequestContext".

Des idées sur ce qui se passe et comment je peux y arriver? thanx

+0

à quoi ressemble votre modèle? – JonC

+0

{% extends "site_base.html" %} {% corps de bloc%}

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

Répondre

3

Vous devrez peut-être réécrire manuellement l'affichage d'enregistrement django. On dirait qu'il y a un issue with how Jinja likes to do things and how Django wants to configure template loaders..

Pour voir les vues d'authentification standard, regardez sous "packages de site" dans votre installation python.

Vous pouvez essayer d'envelopper les vues standard auth comme celui-ci:

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) 

I essentiellement importé vues standard auth de Django et les appela avec moi-même, qui ont la décoration csrf_protect. Ça vaut le coup.

+0

Votre réponse est un peu trop compliquée, donc je vais devoir l'étudier petit à petit, et surtout comment configurer une vue personnalisée. merci beaucoup – mgPePe

2

Avez-vous également installé le système standard Django Templating? Cela sera nécessaire pour la plupart des applications distribuées avec des modèles.

Pour CSRF, un processeur de contexte insère la variable 'csrf_token' dans le contexte de réponse qu'il extrait du middleware s'il est activé. Maintenant, tout ce que vous avez à faire est de vous assurer que c'est en dehors de votre forme.

Ceci est directement hors de django.core, et est sujet à changement à tout moment.

 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) 

Cependant, voyant que, tout ce que vous avez vraiment besoin de savoir est que vous devez avoir un type d'entrée nommé csrfmiddlewaretoken avec la valeur de context.get (« csrf_token », « ») au sein de votre forme et c'est tout elle a écrit.

+0

J'ai le même problème, Que se passe-t-il si je ne vois pas le type d'entrée nommé csrfmiddlewaretoken quand je regarde la source du template? – juankysmith

+0

@juanky, le point est qu'il doit être inclus dans vos modèles. django fournit un processeur de contexte '{% csrf_token%}' à cette fin. Si vous utilisez un langage de modèle différent, vous devez vous assurer que le code HTML figurant dans le code ci-dessus est inclus dans chaque formulaire de vos modèles. –

+0

J'ai {% csrf_token%} dans tous les formulaires, mes vues utilisent RequestContext au lieu de request et les TEMPLATE_CONTEXT_PROCESSORS sont ordonnés correctement dans settings.py ... mais je reçois toujours ce message stupide 'CSRF token manquant ou incorrect' – juankysmith

1

La réponse la plus simple à cette question est de simplement ajouter {% csrf_token%} dans la balise de formulaire dans votre modèle/html.

-6

Je viens du middleware mis hors csrf dans les paramètres comme si, et maintenant il fonctionne:

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

Maintenant vous avez pas de protection CSRF. Cela ne devrait * pas * être marqué comme la bonne réponse! – spookylukey

+2

MAUVAIS MAUVAIS MAUVAIS MAUVAIS MAUVAIS! –

2

Cette réponse est pas spécifique à django-enregistrement, mais juste en utilisant Django avec Jinja2 en général.

CsrfViewMiddleware de Django définit le cookie csrf_token s'il détermine que vous avez accédé au membre de contexte csrf_token. Malheureusement, le rendu de Jinja2 ne se produit qu'après l'exécution du middleware de Django. Par conséquent, le cookie n'est pas défini et, par conséquent, ne correspond pas au formulaire et vous obtiendrez l'erreur 403.Pour contourner ce problème, vous devez accéder au contexte ['csrf_token'] à un moment donné avant de terminer le traitement de la réponse.

Si vous utilisez des vues de classe, vous pouvez créer 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) 

Et puis dans votre classe de vue:

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

Si vous n'êtes pas à l'aide de classes vues, vous pouvez faire quelque chose comme:

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

Ou peut-être le singe render_to_reponse Patch avec la logique de la classe, au dessus.