2012-05-19 13 views
11

Ho letto Django - CSRF verification failed e diverse domande (e risposte) relative al metodo django e al metodo POST. Uno dei migliori-ma-non-lavoro-per me-risposta è https://stackoverflow.com/a/4707639/755319Il metodo POST restituisce sempre 403 Proibito

Tutte le risposte approvate suggeriscono almeno 3 cose:

  1. Usa RequestContext come terzo parametro di render_to_response_call
  2. Add {% csrf_token%} in ogni forma con metodo POST
  3. Controllare le MIDDLEWARE_CLASSES in settings.py

ho fatto esattamente come suggerito, ma l'errore ancora apparso. Io uso django 1.3.1 (da Ubuntu 12.04 repository) e Python 2.7 (di default da Ubuntu)

Questa è la mia opinione:

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

e questo è il mio modello (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 %} 

Ho riavviato il server, ma l'errore 403 vietato è ancora lì, dicendo che la verifica CSRF non è riuscita.

Sono 2 domande:

  1. come riparare questo errore?
  2. Perché è così difficile fare un "POST" in django, voglio dire c'è qualche ragione specifica per renderlo così prolisso (vengo da PHP, e non ho mai trovato un problema simile prima)?

risposta

3

provare a mettere in RequestContext render_to_response della vista search_form:

context_instance=RequestContext(request) 
+0

di che funziona, grazie per la tua risposta. Ma come e perché? Puoi per favore dare una spiegazione? – goFrendiAsgard

+2

https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#how-to-use-it - leggi il punto # 3 – zubinmehta

+2

Perché 'csrf_token' deve essere creato nella tua vista in modo che django possa passare al modello. Nella tua situazione, dato che la tua vista di ricerca non crea un token, '{% csrf_token%}' nel tuo modello è 'stringa vuota (Nessuno)' e la pagina dei risultati non riesce sulla verifica – FallenAngel

0

È inoltre possibile utilizzare

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

invece di

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

perché direct_to_template aggiunge RequestContext aut omatically. Nota che direct_to_template sarà deprecato e django offre invece CBV TemplateView.

RequestContext consente di utilizzare processori di contesto. E questo è un tuo errore: {% csrf_token %} ha generato una stringa vuota e hai ottenuto 403.

+0

Ciao, grazie per il tuo commento, sembra che dovrei prendere in considerazione molte cose prima di familiarizzare con django: D – goFrendiAsgard

5

Il modo più semplice per evitare tali problemi è usare il collegamento 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}) 
+0

+1 per 'django.me' – San4ez

+0

Devi provarlo presto, sembra molto chiaro, grazie per la tua risposta. C'è qualche contro di usare questo metodo? Mi chiedo perché la documentazione e il djangobook forniscano una sintassi così dettagliata se c'è una sintassi così chiara – goFrendiAsgard

+0

So che questo è un thread vecchio, ma l'ho aggiornato per chiarire ulteriormente il metodo di ricerca. Speriamo che questo sia (più) utile. –

9

Forse ho sbagliato tuttavia ho trovato le soluzioni di cui sopra piuttosto complesse.

ciò che ha funzionato per me è stato semplicemente includere il mio token csrf nella mia richiesta di post.

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

Ha funzionato per me - grazie! – skaz

0

è necessario utilizzare RequestContext con la vostra risposta

ad esempio in view.py file di

from django.template import RequestContext 

def home(request): 
    return render_to_response('home.html',RequestContext(request, {})) 
2

La risposta è 403 bcoz, Django richiede un token CSRF (incluso nei dati post) in ogni richiesta POST effettuata.

Ci sono vari modi per fare questo, come:

Acquisire il gettone da biscotto e il metodo è stato spiegato in un articolo enter link description here

o

È possibile accedervi da DOM utilizzando {{ csrf_token}}, disponibile nel modello

Così ora con il secondo metodo:

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); 
    } 
}); 
1

Questa risposta è per le persone che potrebbero incontrare lo stesso problema in futuro.

Il tag del modello CSRF {{csrf_token}} richiesto per i form in Django impedisce contro i falsi falsi. CSRF consente a un sito dannoso visitato dal browser di un cliente di effettuare richieste al proprio server. Quindi il csrf_token fornito da django rende semplice proteggere il tuo server e il tuo sito django da questo tipo di attacco dannoso. Se il tuo modulo non è protetto da csrf_token, django restituisce una 403 pagina proibita. Questa è una forma di protezione per il tuo sito web, specialmente quando il token non è stato lasciato intenzionalmente.

Ma ci sono scenari in cui un sito django non vorrebbe proteggere le sue forme usando csrf_token. Ad esempio, ho sviluppato un'applicazione USSD e una funzione di visualizzazione è necessaria per ricevere una richiesta POST dall'API USSD. Dovremmo notare che la richiesta POST non proviene da un modulo sul client, quindi il rischio di CSRF è impossibile, dal momento che un sito dannoso non può inviare richieste. La richiesta POST viene ricevuta quando un utente compone un codice USSD e non quando viene inviato un modulo.

In altre parole, ci sono situazioni in cui una funzione richiederà una richiesta POST e non ci sarebbe bisogno di {{csrf_token}}.

Django ci fornisce un decoratore @csrf_exempt. Questo decoratore è considerato esente dalla protezione garantita dal 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 fornisce anche un altro decoratore che esegue la stessa funzione con {{csrf_token}}, ma non rifiuta richiesta in ingresso. Questo decoratore è @requires_csrf_token. Per esempio:

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

L'ultima decoratore che verranno menzionati in questo post fa esattamente la stessa cosa di {{csrf_token}} e si chiama @csrf_protect. Tuttavia, l'uso di questo decoratore di per sé non è una buona pratica perché potresti dimenticarti di aggiungerlo alle tue opinioni.Ad esempio:

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

Di seguito sono riportati alcuni collegamenti che guideranno e spiegheranno meglio.

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

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

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

Problemi correlati