2012-05-19 17 views
11

He leído Django - CSRF verification failed y varias preguntas (y respuestas) relacionadas con el método django y POST. Uno de los mejores-pero-no-trabajo-para-mí respuesta es https://stackoverflow.com/a/4707639/755319Método POST siempre devuelve 403 Prohibido

Todas las respuestas aprobadas sugieren al menos 3 cosas:

  1. Uso RequestContext como tercer parámetro de render_to_response_call
  2. Agregar {}% csrf_token% en todas sus formas con el método POST
  3. Verificar los MIDDLEWARE_CLASSES en settings.py

que he hecho exactamente como se sugiere, pero el error sigue apareció. Yo uso Django 1.3.1 (de ubuntu 12.04 repositorio) y Python 2.7 (por defecto de Ubuntu)

Este es mi punto de vista:

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

y este es mi plantilla (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 %} 

He reiniciado el servidor, pero el error prohibido 403 sigue ahí, diciéndome que la verificación de CSRF falló.

He 2 preguntas:

  1. Cómo corregir este error?
  2. ¿Por qué es tan difícil hacer un "POST" en django, quiero decir, hay alguna razón específica para hacerlo tan detallado (vengo de PHP, y nunca he encontrado un problema así antes)?

Respuesta

3

trate de poner en RequestContext render_to_response de la vista search_form:

context_instance=RequestContext(request) 
+0

de que funciona, gracias por su respuesta. ¿Pero cómo y por qué? ¿Puedes dar una explicación? – goFrendiAsgard

+2

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

+2

Porque 'csrf_token' se debe crear en su vista para que django pueda pasar a la plantilla. En su situación, dado que su vista de búsqueda no crea un token, '{% csrf_token%}' en su plantilla es 'cadena vacía (Ninguna)' y la página de resultados falla en la verificación – FallenAngel

0

También puede utilizar

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

en lugar de

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

porque direct_to_template añade RequestContext aut omaticamente Pero tenga en cuenta que direct_to_template va a estar en desuso y django ofrece usar CBV TemplateView en su lugar.

RequestContext le permite utilizar los procesadores de contexto. Y este es su error: {% csrf_token %} cadena vacía superada y tiene 403.

+0

Hola, gracias para su comentario, parece que debería considerar muchas cosas antes de familiarizarme con django: D – goFrendiAsgard

5

La manera más fácil de evitar tales problemas es usar el atajo 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 para 'django.me' – San4ez

+0

Debo probar esto pronto, parece muy claro, gracias por su respuesta. ¿Hay algún inconveniente de usar este método? Me pregunto por qué la documentación y djangobook proporcionan una sintaxis tan detallada si hay una sintaxis clara – goFrendiAsgard

+0

Sé que este es un hilo antiguo, pero lo actualicé para aclarar aún más el método de búsqueda. Espero que esto sea ahora (más) útil. –

9

I mal pero encontré las soluciones anteriores bastante complejas.

lo que funcionó para mí fue simplemente incluir mi token csrf en mi solicitud de publicación.

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

Funcionó para mí, ¡gracias! – skaz

0

Es necesario utilizar RequestContext con su respuesta

por ejemplo en view.py archivo

from django.template import RequestContext 

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

La respuesta es de 403 bcoz, Django requiere un token CSRF (incluido en los datos de envío) en cada solicitud POST que realice.

Hay varias maneras de hacer esto, tales como:

La adquisición de la ficha de galleta y el método se ha explicado en el artículo enter link description here

o

Puede acceder a él desde DOM usando {{ csrf_token}}, disponible en la plantilla

Así que ahora con el segundo método:

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

Esta respuesta es para las personas que puedan tener contacto con este mismo problema en el futuro.

La etiqueta de plantilla CSRF {{csrf_token}} que se requiere para las formas en Django previenen contra Cross Site Request falsificaciones. CSRF hace posible que un sitio malicioso que ha sido visitado por el navegador de un cliente para hacer peticiones a su propio servidor. De ahí la csrf_token proporcionada por Django hace que sea sencillo para el servidor de Django y sitio para estar protegidos contra este tipo de ataques maliciosos. Si su formulario no está protegido por csrf_token, django devuelve una página prohibida 403. Esta es una forma de protección para su sitio web, especialmente cuando el token no se omite intencionalmente.

Pero hay escenarios en los que un sitio Django no le gustaría para proteger sus formas mediante el csrf_token. Por ejemplo, desarrollé una aplicación USSD y se requiere una función de vista para recibir una solicitud POST de la API de USSD. Debemos tener en cuenta que la solicitud POST no era de un formulario en el cliente, por lo tanto el riesgo de CSRF imposible, ya que un sitio malicioso no puede enviar solicitudes. La solicitud POST se recibe cuando un usuario marca un código USSD y no cuando se envía un formulario.

En otras palabras, hay situaciones en las que una función necesitará obtener una solicitud POST y no habrá necesidad de {{csrf_token}}.

Django nos proporciona un decorador @csrf_exempt. Este decorador marca una vista como estar exento de la protección garantizada por el 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 también proporciona otro decorador que realiza la misma función con {{csrf_token}}, pero no rechaza la petición entrante. Este decorador es @requires_csrf_token. Por ejemplo:

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

La última decorador que se menciona en este post hace exactamente lo mismo que {{}} csrf_token y se llama @csrf_protect. Sin embargo, el uso de este decorador por sí solo no es una buena práctica porque es posible que olvide agregarlo a sus vistas.Por ejemplo:

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

A continuación se muestran algunos enlaces que guiarán y explicarán mejor.

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

Cuestiones relacionadas