2012-04-30 24 views
9

Intento crear un sitio web muy simple donde se puedan agregar datos en la base de datos sqlite3. Tengo un formulario POST con dos entradas de texto.Falló la verificación de CSRF. Solicitud cancelada

index.html:

{% if top_list %} 
    <ul> 
    <b><pre>Name Total steps</pre></b> 
    {% for t in top_list %} 
     <pre>{{t.name}} {{t.total_steps}}</pre> 
    {% endfor %} 
    </ul> 
    {% else %} 
    <p>No data available.</p> 
{% endif %} 
<br> 
<form action="/steps_count/" method="post"> 
    {% csrf_token %} 
    Name: <input type="text" name="Name" /><br /> 
    Steps: <input type="text" name="Steps" /><br /> 
    <input type="submit" value="Add" /> 
</form> 

forms.py:

from django import forms 
from steps_count.models import Top_List 

class Top_List_Form(forms.ModelForm): 
    class Meta: 
     model=Top_List 

views.py:

# Create your views here. 
from django.template import Context, loader 
from django.http import HttpResponse 
from steps_count.models import Top_List 
from steps_count.forms import Top_List_Form 
from django.template import RequestContext 
from django.shortcuts import get_object_or_404, render_to_response 

def index(request): 

if request.method == 'POST': 
    #form = Top_List_Form(request.POST) 
    print "Do something" 
else: 
    top_list = Top_List.objects.all().order_by('total_steps').reverse() 
    t = loader.get_template('steps_count/index.html') 
    c = Context({'top_list': top_list,}) 
    #output = ''.join([(t.name+'\t'+str(t.total_steps)+'\n') for t in top_list]) 
    return HttpResponse(t.render(c)) 

Sin embargo, al hacer clic en el botón "enviar", consigo el error 403:

CSRF verification failed. Request aborted. 

He incluido {% csrf_token %} en index.html. Sin embargo, si se trata de un problema de RequestContext, realmente no tengo idea de dónde y cómo usarlo. Quiero que todo suceda en la misma página (index.html).

Respuesta

13

Utilice render shortcut que agrega RequestContext automáticamente.

from django.http import HttpResponse 
from django.shortcuts import get_object_or_404, render 
from steps_count.models import Top_List 
from steps_count.forms import Top_List_Form 


def index(request): 

    if request.method == 'POST': 
     #form = Top_List_Form(request.POST) 
     return HttpResponse("Do something") # methods must return HttpResponse 
    else: 
     top_list = Top_List.objects.all().order_by('total_steps').reverse() 
     #output = ''.join([(t.name+'\t'+str(t.total_steps)+'\n') for t in top_list]) 
     return render(request,'steps_count/index.html',{'top_list': top_list}) 
+0

Muchas gracias, funciona! – Bebe

1

Debe utilizar

from django.shortcuts import render_to_response 
. 
. 
. 
return render_to_response("steps_count/index.html", {'top_list': top_list}, context_instance=RequestContext(request)) 

en lugar de

return HttpResponse(t.render(c)) 

Lea sobre "procesadores de contexto" y ver this enlace para obtener detalles sobre cómo la protección CSRF trabaja en Django.

ACTUALIZACIÓN

leí mal la HttpResponse como render_to_response. Actualicé mi respuesta anterior.

1

Un error común aquí es usar render_to_response (esto se usa comúnmente en tutoriales más antiguos), que no incluye automáticamente RequestContext. Render lo incluye automáticamente.

Aprendí esto al crear una nueva aplicación mientras seguía un tutorial y CSRF no funcionaba para las páginas de la nueva aplicación.

4

Cuando encuentre este tipo de mensaje, significa que falta el token CSRF o es incorrecto. Entonces tienes dos opciones.

  1. Para las formas de la POST, es necesario asegurar:

    • Su navegador acepta cookies.

    • En la plantilla, hay una etiqueta de plantilla {% csrf_token%} dentro de cada formulario POST que se dirige a una URL interna.

  2. La otra forma sencilla simplemente se comenta una línea (No recomendado) ('django.middleware.csrf.CsrfViewMiddleware') en MIDDLEWARE_CLASSES desde la pestaña de configuración.

    MIDDLEWARE_CLASSES = (
        'django.contrib.sessions.middleware.SessionMiddleware', 
        'django.middleware.common.CommonMiddleware', 
        # 'django.middleware.csrf.CsrfViewMiddleware', 
        'django.contrib.auth.middleware.AuthenticationMiddleware', 
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 
        'django.contrib.messages.middleware.MessageMiddleware', 
        'django.middleware.clickjacking.XFrameOptionsMiddleware', 
    

    )

+0

Gracias por la segunda parte. ¡Simplemente no necesito eso! :) – SaurabhJinturkar

+0

Desactivar CSRF es * NO * una solución. Por favor no hagas eso. (parte 2 de la respuesta) – elnygren

0
function yourFunctionName(data_1,data_2){ 
     context = {} 
     context['id'] = data_1 
     context['Valid'] = data_2 
     $.ajax({ 
      beforeSend:function(xhr, settings) { 
        function getCookie(name) { 
          var cookieValue = null; 
          if (document.cookie && document.cookie != '') { 
           var cookies = document.cookie.split(';'); 
           for (var i = 0; i < cookies.length; i++) { 
            var cookie = jQuery.trim(cookies[i]); 
            if (cookie.substring(0, name.length + 1) == (name + '=')) { 
             cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
             break; 
            } 
           } 
          } 
          return cookieValue; 
         } 
         if (settings.url == "your-url") 
          xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); 
        }, 

      url: "your-url", 
      type: "POST", 
      data: JSON.stringify(context), 
      dataType: 'json', 
      contentType: 'application/json' 
     }).done(function(data) { 
    }); 
+0

Deberías escribir tu ajax así. –

0
if you put {%csrf_token%} and still you have the same issue, please try to change your angular version. because its works for me. initially i faced this issue while using angular 1.4.x version . after i degrade it into angular 1.2.8, my problem was fixed. 
and dont forgot to add angular-cookies.js and put this on your js file. 
if you using post request. 
"app.run(function($http, $cookies) { 
    console.log($cookies.csrftoken) 
    $http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken; 
}); 
" 
0

En su cabecera HTML, añadir

<meta name="csrf_token" content="{{ csrf_token }}"> 

Luego, en sus JS/config angular:

app.config(function($httpProvider){ 
    $httpProvider.defaults.headers.post['X-CSRFToken'] = $('meta[name=csrf_token]').attr('content'); 
} 
1

que puede haber perdido añadiendo lo siguiente a su formulario:

{% csrf_token %} 
Cuestiones relacionadas