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,
})
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.
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 %}
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>