it-swarm.com.de

POST Methode immer 403 zurückgeben Verboten

Ich habe gelesen Django - CSRF-Überprüfung fehlgeschlagen und mehrere Fragen (und Antworten), die sich auf Django und die Methode POST beziehen. Eine der besten, aber nicht funktionierenden Antworten für mich ist https://stackoverflow.com/a/4707639/755319

Alle genehmigten Antworten legen mindestens drei Dinge nahe:

  1. Verwenden Sie RequestContext als dritten Parameter von render_to_response_call
  2. Fügen Sie in jeder Form {% csrf_token%} mit der Methode POST hinzu
  3. Überprüfen Sie die MIDDLEWARE_CLASSES in settings.py

Ich habe genau wie vorgeschlagen gemacht, aber der Fehler ist immer noch aufgetreten. Ich benutze Django 1.3.1 (von Ubuntu 12.04 Repository) und Python 2.7 (Standard von Ubuntu)

Dies ist meine Ansicht:

# 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)

und das ist meine Vorlage (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 %}

Ich habe den Server neu gestartet, aber der verbotene Fehler 403 ist immer noch vorhanden und weist darauf hin, dass die CSRF-Überprüfung fehlgeschlagen ist.

Ich habe 2 Fragen:

  1. Wie kann man diesen Fehler beheben?
  2. Warum ist es so schwer in Django einen "POST" zu machen? Ich meine, gibt es einen bestimmten Grund, es so wortreich zu machen (ich komme aus PHP und habe noch nie ein solches Problem gefunden)?
13
goFrendiAsgard

Versuchen Sie, RequestContext in die render_to_response-Ansicht der search_form-Ansicht zu setzen: 

context_instance=RequestContext(request)
3
zubinmehta

Ich bin vielleicht falsch, aber ich fand die obigen Lösungen ziemlich komplex. 

was für mich funktionierte, war einfach, mein CSRF-Token in meine Post-Anfrage aufzunehmen.

$.ajax({
    type: "POST",
    url: "/reports/",
    data: { csrfmiddlewaretoken: "{{ csrf_token }}",   // < here 
            state:"inactive" 
          },
    success: function() {
        alert("pocohuntus")
        console.log("prototype")
    }
})
11
laycat

Der einfachste Weg, solche Probleme zu vermeiden, ist die Verwendung der render - Verknüpfung.

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})
5
Burhan Khalid

Diese Antwort richtet sich an Personen, die möglicherweise in der Zukunft auf dieses Problem stoßen. 

Das CSRF {{csrf_token}}-Vorlagen-Tag, das für Formulare in Django erforderlich ist, verhindert Cross Site Request-Fälschungen. CSRF ermöglicht es einer böswilligen Website, die der Browser eines Kunden besucht hat, Anforderungen an Ihren eigenen Server zu stellen. Mit dem von Django bereitgestellten csrf_token ist es daher einfach, Ihren Django-Server und Ihre Website vor dieser Art von böswilligen Angriffen zu schützen. Wenn Ihr Formular nicht durch csrf_token geschützt ist, gibt Django eine 403 verbotene Seite zurück. Dies ist ein Schutz für Ihre Website, insbesondere wenn der Token nicht absichtlich ausgelassen wurde. 

Es gibt jedoch Szenarien, in denen eine Django-Site ihre Formulare nicht mit csrf_token schützen möchte. Ich habe zum Beispiel eine USSD-Anwendung entwickelt, und eine Ansichtsfunktion ist erforderlich, um eine POST -Anforderung von der USSD-API zu erhalten. Wir sollten beachten, dass die POST -Anforderung nicht von einem Formular auf dem Client stammt, daher ist das Risiko einer CSRF nicht möglich, da eine böswillige Website keine Anforderungen einreichen kann. Die Anforderung POST wird empfangen, wenn ein Benutzer einen USSD-Code wählt und nicht, wenn ein Formular gesendet wird. 

Mit anderen Worten, es gibt Situationen, in denen eine Funktion eine POST -Anforderung abrufen muss und {{csrf_token}} nicht erforderlich wäre.

Django liefert uns einen Dekorateur @csrf_exempt. Dieser Dekorateur markiert eine Ansicht als vom Schutz der Middleware ausgenommen. 

from Django.views.decorators.csrf import csrf_exempt
from Django.http import HttpResponse

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

Django bietet auch einen anderen Dekorateur an, der dieselbe Funktion wie {{csrf_token}} ausführt, eingehende Anfragen jedoch nicht ablehnen. Dieser Dekorateur ist @requires_csrf_token. Zum Beispiel:

@requires_csrf_token
def my_view(request):
    c = {}
    # ...
    return render(request, "a_template.html", c)

Der letzte Dekorator, der in diesem Beitrag erwähnt wird, macht genau dasselbe wie {{csrf_token}} und heißt @csrf_protect. Die Verwendung dieses Dekorators an sich ist jedoch keine bewährte Methode, da Sie vergessen könnten, ihn Ihren Ansichten hinzuzufügen. Zum Beispiel:

@csrf_protect
def my_view(request):
    c = {}
    # ...
    return render(request, "a_template.html", c)

Nachfolgend finden Sie einige Links, die Sie besser leiten und erklären werden. 

https://docs.djangoproject.com/de/1.7/ref/contrib/csrf/#module-Django.views.decorators.csrf

https://docs.djangoproject.com/de/1.7/ref/contrib/csrf/

http://www.squarefree.com/securitytips/web-developers.html#CSRF

3
Iyanuoluwa Ajao

Die Antwort lautet 403 bcoz, Django erfordert in jeder POST -Anforderung, die Sie stellen, ein csrf-Token (in den Plandaten enthalten).

Es gibt verschiedene Möglichkeiten, dies zu tun, z.

Das Token vom Cookie und der Methode abrufen wurde in Artikel Linkbeschreibung hier eingeben beschrieben.

oder 

Sie können von DOM aus mit {{csrf_token}} darauf zugreifen, das in der Vorlage verfügbar ist 

Also jetzt mit der zweiten Methode:

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);
  }
});
2
Hiro

Sie können auch verwenden 

direct_to_template(request, 'library/search.html', result) 

anstatt

render_to_response('library/search.html', result, context_instance=RequestContext(request))

weil direct_to_template automatisch RequestContext hinzufügt. Beachten Sie jedoch, dass direct_to_template veraltet sein wird und Django stattdessen CBV TemplateView verwendet.

RequestContext erlaubt die Verwendung von Kontextprozessoren. Und das ist dein Fehler: {% csrf_token %} hat einen leeren String ausgegeben und du hast 403.

0
San4ez

Sie müssen RequestContext mit Ihrer Antwort verwenden 

zum Beispiel in der view.py-Datei

from Django.template import RequestContext

def home(request):
    return render_to_response('home.html',RequestContext(request, {}))
0
DHaval Joshi