J'ai lu Django - La vérification CSRF a échoué et plusieurs questions (et réponses) relatives à Django et à la méthode POST. Une des meilleures solutions, mais qui ne fonctionnent pas pour moi, est https://stackoverflow.com/a/4707639/755319
Toutes les réponses approuvées suggèrent au moins 3 choses:
J'ai fait exactement comme suggéré, mais l'erreur est toujours apparue. J'utilise Django 1.3.1 (du référentiel Ubuntu 12.04) et Python 2.7 (par défaut d'ubuntu)
Ceci est mon point de vue:
# Create your views here.
from Django.template import RequestContext
from Django.http import HttpResponse
from Django.shortcuts import render_to_response
from models import BookModel
def index(request):
return HttpResponse('Welcome to the library')
def search_form(request):
return render_to_response('library/search_form.html')
def search(request):
if request.method=='POST':
if 'q' in request.POST:
q=request.POST['q']
bookModel = BookModel.objects.filter(title__icontains=q)
result = {'books' : bookModel,}
return render_to_response('library/search.html', result, context_instance=RequestContext(request))
else:
return search_form(request)
else:
return search_form(request)
et voici mon modèle (search_form.html):
{% extends "base.html" %}
{% block content %}
<form action="/library/search/" method="post">
{% csrf_token %}
<input type="text" name="q">
<input type="submit" value="Search">
</form>
{% endblock %}
J'ai redémarré le serveur, mais l'erreur 403 interdite est toujours là, indiquant que la vérification CSRF a échoué.
J'ai 2 questions:
Essayez de placer RequestContext dans render_to_response de la vue search_form
context_instance=RequestContext(request)
J'ai peut-être tort, mais j'ai trouvé les solutions ci-dessus plutôt complexes.
ce qui a bien fonctionné pour moi, c’est tout simplement d’inclure mon jeton CSRF dans ma demande de publication.
$.ajax({
type: "POST",
url: "/reports/",
data: { csrfmiddlewaretoken: "{{ csrf_token }}", // < here
state:"inactive"
},
success: function() {
alert("pocohuntus")
console.log("prototype")
}
})
Le moyen le plus simple d'éviter de tels problèmes consiste à utiliser le raccourci render
.
from Django.shortcuts import render
# .. your other imports
def search_form(request):
return render(request, 'library/search_form.html')
def search(request):
q = request.GET.get('q')
results = BookModel.objects.all()
if q:
results = results.filter(title__icontains=q)
return render(request, 'library/search.html', {'result': results})
Cette réponse s'adresse aux personnes susceptibles de rencontrer ce même problème à l'avenir.
La balise de modèle CSRF {{csrf_token}}
requise pour les formulaires dans Django empêche la création de requêtes de type Cross Site Request. CSRF permet à un site malveillant visité par le navigateur d'un client de faire des requêtes sur votre propre serveur. Ainsi, le csrf_token fourni par Django simplifie la protection de votre serveur et de votre site Django contre ce type d'attaque malveillante. Si votre formulaire n'est pas protégé par csrf_token, Django renvoie une page 403 interdite. Il s'agit d'une forme de protection pour votre site Web, en particulier lorsque le jeton n'a pas été oublié intentionnellement.
Mais il existe des scénarios dans lesquels un site Django ne voudrait pas protéger ses formulaires à l’aide de csrf_token. Par exemple, j'ai développé une application USSD et une fonction d'affichage est requise pour recevoir une demande POST de l'API USSD. Il convient de noter que la demande POST ne provenait pas d'un formulaire sur le client, ce qui rendait le risque de CSRF impossible, puisqu'un site malveillant ne peut pas soumettre de demandes. La demande POST est reçue lorsqu'un utilisateur compose un code USSD et non lorsqu'un formulaire est soumis.
En d'autres termes, il existe des situations dans lesquelles une fonction doit obtenir une demande POST et où il n'est pas nécessaire d'utiliser {{csrf_token}}.
Django nous fournit un décorateur @csrf_exempt
. Ce décorateur marque une vue comme étant exempte de la protection assurée par le middleware.
from Django.views.decorators.csrf import csrf_exempt
from Django.http import HttpResponse
@csrf_exempt
def my_view(request):
return HttpResponse('Hello world')
Django fournit également un autre décorateur qui remplit la même fonction avec {{csrf_token}}
, mais il ne rejette pas les demandes entrantes. Ce décorateur est @requires_csrf_token
. Par exemple:
@requires_csrf_token
def my_view(request):
c = {}
# ...
return render(request, "a_template.html", c)
Le dernier décorateur mentionné dans cet article fait exactement la même chose que {{csrf_token}} et s'appelle @csrf_protect
. Cependant, l'utilisation de ce décorateur en soi n'est pas la meilleure pratique car vous pourriez oublier de l'ajouter à vos points de vue. Par exemple:
@csrf_protect
def my_view(request):
c = {}
# ...
return render(request, "a_template.html", c)
Vous trouverez ci-dessous des liens qui guideront et expliqueront mieux.
https://docs.djangoproject.com/fr/1.7/ref/contrib/csrf/#module-Django.views.decorators.csrf
https://docs.djangoproject.com/fr/1.7/ref/contrib/csrf/
http://www.squarefree.com/securitytips/web-developers.html#CSRF
La réponse est 403 bcoz, Django requiert un jeton CSRF (inclus dans les données de publication) dans chaque POST demande que vous effectuez.
Il y a différentes façons de le faire, telles que:
L’acquisition du jeton à partir du cookie et de la méthode a été expliquée dans article entrez la description du lien ici
ou
Vous pouvez y accéder depuis DOM en utilisant {{csrf_token}}, disponible dans le modèle.
Alors maintenant, en utilisant la deuxième méthode:
var post_data = {
...
'csrfmiddlewaretoken':"{{ csrf_token }}"
...
}
$.ajax({
url:'url',
type:'POST'
data:post_data,
success:function(data){
console.log(data);
},
error:function(error){
console.log(error);
}
});
Vous pouvez aussi utiliser
direct_to_template(request, 'library/search.html', result)
au lieu de
render_to_response('library/search.html', result, context_instance=RequestContext(request))
parce que direct_to_template
ajoute RequestContext
automatiquement. Notez cependant que direct_to_template
sera obsolète et Django vous proposera d'utiliser CBV TemplateView
à la place.
RequestContext
vous permet d'utiliser des processeurs de contexte. Et voici votre erreur: {% csrf_token %}
a généré une chaîne vide et vous avez 403.
Vous devez utiliser RequestContext
avec votre réponse
par exemple dans le fichier view.py
from Django.template import RequestContext
def home(request):
return render_to_response('home.html',RequestContext(request, {}))