La vérification de Django - CSRF a échoué

Je reçois un message d'échec de vérification CSRF en essayant de créer un formulaire simple à partir d'un tutoriel. J'ai fait un peu de recherche sur ce qu'est la vérification CSRF, et à ma connaissance, pour l'utiliser, vous avez besoin d'une de ces balises csrf_token dans votre html, mais je n'ai pas ça

Voici mon modèle:

<form action="/testapp1/contact/" method="post">
    {{ form.as_p }}
    <input type="submit" value="Submit" />
</form>

Assez simple, situé au contact.html

Voici mon urlconf: de django.conf.URL.importation par défaut *

urlpatterns=patterns('testapp1.views',
    (r'^$', 'index'),
    (r'^contact/$','contact')
)

Le nom de l'application est testapp1. Quand je tape mon url (http://localhost:8000/testapp1/contact), je vais correctement au formulaire. Ensuite, lorsque je soumets le formulaire, je reçois l'erreur de vérification.

Voici mon point de vue bien que je ne pense pas que ce soit pertinent:

def contact(request):
    if request.method == 'POST': # If the form has been submitted...
        form = ContactForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            subject = form.cleaned_data['subject']
            message = form.cleaned_data['message']
            sender = form.cleaned_data['sender']
            cc_myself = form.cleaned_data['cc_myself']
            recipients = ['info@example.com']
            if cc_myself:
                recipients.append(sender)
            print 'Sending Mail:'+subject+','+message+','+sender+','+recipients
            return HttpResponseRedirect('/thanks/') # Redirect after POST
    else:
        form = ContactForm() # An unbound form

    return render_to_response('contact.html', {
        'form': form,
    })
23
demandé sur JPC 2010-12-28 19:43:02

3 réponses

Le correctif

1. inclure {% csrf_token %} à l'intérieur de la balise form dans le modèle.

2. si pour une raison quelconque vous utilisez render_to_response sur Django 1.3 et supérieur, remplacez-le par la fonction render . Remplacer ceci:

# Don't use this on Django 1.3 and above
return render_to_response('contact.html', {'form': form})

Avec ceci:

return render(request, 'contact.html', {form: form})

Le render la fonction a été introduite dans Django version 1.3 - si vous utilisez une ancienne version de comme 1.2 ou au-dessous de, vous devez utiliser render_to_response avec un RequestContext:

# Deprecated since version 2.0
return render_to_response('contact.html', {'form': form},
                   context_instance=RequestContext(request))

Qu'est-ce que la protection CSRF et pourquoi le voudrais-je?

C'est une attaque où un ennemi peut forcer vos utilisateurs à faire des choses désagréables comme transférer des fonds, changer leur adresse e-mail, et ainsi de suite:

Cross-Site Request Forgery (CSRF) est une attaque qui force un utilisateur final à exécuter des actions indésirables sur une application web dans laquelle il est actuellement authentifié. Les attaques CSRF ciblent spécifiquement les demandes de changement d'état, pas le vol de données, car l'attaquant n'a aucun moyen de voir la réponse à la forgé demande. Avec un peu d'aide de l'ingénierie sociale (comme l'envoi d'un lien par e-mail ou chat), un attaquant peut tromper les utilisateurs d'une application web dans l'exécution des actions de l'attaquant du choix. Si la victime est un utilisateur normal, une attaque CSRF réussie peut forcer l'utilisateur à effectuer des demandes de changement d'état telles que le transfert de fonds, la modification de son adresse e-mail, etc. Si la victime est un compte administratif, CSRF peut compromettre l'ensemble de l'application web. Source: Le Projet Open Web Application Security

Même si vous ne vous souciez pas de ce genre de chose maintenant, l'application peut croître, donc la meilleure pratique est de garder la protection CSRF.

La protection CSRF ne devrait-elle pas être facultative?

Il est facultatif mais activé par défaut (le middleware CSRF est inclus par défaut). Vous pouvez l'éteindre:

  • pour une vue particulière en la décorant avec le csrf_excempt décorateur.
  • pour chaque vue en supprimant le middleware CSRF de la liste des middlewares à settings.py

Si vous l'éteignez l'échelle du système, vous pouvez l'activer pour une vue particulière en la décorant avec les csrf_protect décorateur.

34
répondu Paulo Scardine 2018-05-14 14:11:18

Views.py:

from django.shortcuts import render_to_response
from django.template import RequestContext

def my_view(request):
    return render_to_response('mytemplate.html', context_instance=RequestContext(request)) 

Mytemlate.html:

<form action="/someurls/" method="POST">{% csrf_token %}
3
répondu hustljian 2013-01-10 11:16:17

Pour Django 1.4

Settings.py

MIDDLEWARE_CLASSES = (
...
'django.middleware.csrf.CsrfViewMiddleware',
)

View.py

from django.template.defaulttags import csrf_token
from django.shortcuts import render

@csrf_token
def home(request):
    """home page"""
    return render(request,
        'template.html',
            {}
    )

Modèle.html

<form action="">
    {% csrf_token %}
....
</form>
2
répondu nk9 2012-07-17 18:10:37