2013-09-15 2 views
2

Я использую библиотеку Daxice для создания вызовов AJAX в своем приложении Django. Когда я создаю POST метод на форме я получаю указанную ошибку:Сбой проверки CSRF. Запрос прерван. // Dajaxice, Ajax

Forbidden (403) 
CSRF verification failed. Request aborted. 

Мой settings.py есть:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
) 

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth', 
    'django.core.context_processors.debug', 
    'django.core.context_processors.i18n', 
    'django.core.context_processors.media', 
    'django.core.context_processors.static', 
    'django.core.context_processors.request', 
    'django.contrib.messages.context_processors.messages', 
    'django.core.context_processors.csrf', 
) 

Мой urls.py

from django.conf.urls import patterns, include, url 
from django.contrib.staticfiles.urls import staticfiles_urlpatterns 
from dajaxice.core import dajaxice_autodiscover, dajaxice_config 
dajaxice_autodiscover() 

urlpatterns = patterns('', 
    url(dajaxice_config.dajaxice_url, include('dajaxice.urls')), 
    url(r'^$', 'apps.views.home'), 
) 

urlpatterns += staticfiles_urlpatterns() 

Мои взгляды. py:

from django.http import HttpResponse 
from django.template import loader, Context 

from django.core.context_processors import csrf 

def home(request): 
    t = loader.get_template('index.html') 
    html = t.render(Context()) 
    return HttpResponse(html) 

Мой шаблон index.html:

{% load dajaxice_templatetags %} 

<html> 
    <head> 
    <title>My base template</title> 

    <script src="http://code.jquery.com/jquery-latest.min.js" 
     type="text/javascript"></script> 

    {% dajaxice_js_import %} 

    <script type="text/javascript"> 

    function shout(data){ 
     alert(data.message) 

    } 

    </script> 
    </head> 
    <body> 

    <form method="POST" action="">{% csrf_token %} 
     Page: <input type="text" name="page"><br> 
     From: <input type="text" name="from"> (From < To) <br> 
     To: <input type="text" name="to"> (returns results before that day)<br> 
     <input type="submit" onclick="Dajaxice.apps.hello(shout);" value="Submit"> 
    </form> 

    <br> 
    <br> 

    <input type="button" onclick="Dajaxice.apps.hello(shout);" value="Get message from server!"> 

    </body> 
</html> 

И мой ajax.py:

import simplejson 
from dajaxice.decorators import dajaxice_register 

@dajaxice_register(method='GET') 
@dajaxice_register(method='POST', name='other_post') 
def hello(request): 
    return simplejson.dumps({'message':'Hello from Python!'}) 

Если я нажимаю на кнопку, сообщение получает извещение. Когда я отправлю форму, я получаю эту ошибку. Как я могу это исправить?

Наконец, я считаю, что я исправил все возможности для отображения CSRF на странице отладки:

In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure: 
Your browser is accepting cookies. 
The view function uses RequestContext for the template, instead of Context. 
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL. 
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data. 
+0

какая версия django вы используете? –

+0

@FoxMaSk '1.5.2' – Diolor

ответ

1

Хорошо, я думаю, что я получил его. В строке:

<form> 
... 
<input type="submit" onclick="Dajaxice.apps.hello(shout);" value="Submit"></form> 
... 
</form> 

Если type является button он работает. Это должно быть что-то с поведением сервера запроса submit. Я не эксперт, чтобы объяснить, почему это происходит, поэтому, если кто-то может объяснить, я бы с радостью дал голос.

+0

Если вы говорите о кнопке в своем втором типе ввода, это нормально, что работает, поскольку она не в форме. –

+0

Я никогда не мог отслеживать это, но я видел, что скрытое поле ввода, сгенерированное тегом шаблона {% csrf_token%}, немного шелушится (и использует неправильный токен CSRF). Для целей отладки вы можете добавить токен CSRF в страницы, используя: Затем проверьте источник на странице и посмотреть, соответствует ли скрытый вход токен csrf, который присутствует в голове. –

1

По docs вы можете отправить CSRF-маркер на каждом запросе Ajax-пост, если запустить этот сценарий первый:

function csrfSafeMethod(method) { 
    // these HTTP methods do not require CSRF protection 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
} 
function sameOrigin(url) { 
    // test that a given url is a same-origin URL 
    // url could be relative or scheme relative or absolute 
    var host = document.location.host; // host + port 
    var protocol = document.location.protocol; 
    var sr_origin = '//' + host; 
    var origin = protocol + sr_origin; 
    // Allow absolute or scheme relative URLs to same origin 
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || 
     (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || 
     // or any other URL that isn't scheme relative or absolute i.e relative. 
     !(/^(\/\/|http:|https:).*/.test(url)); 
} 
$.ajaxSetup({ 
    beforeSend: function(xhr, settings) { 
     if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) { 
      // Send the token to same-origin, relative URLs only. 
      // Send the token only if the method warrants CSRF protection 
      // Using the CSRFToken value acquired earlier 
      xhr.setRequestHeader("X-CSRFToken", csrftoken); 
     } 
    } 
}); 

написано в JQuery. Если вы хотите ваниль js, посетите docs

1

Dajaxice выполняет обработку CSRF для вас, вам не нужен какой-либо пользовательский код jQuery beforeSend.

Но вам нужно предоставить Dajaxice доступ к вашему CSRF-файлу. Поэтому:

Удостоверьтесь, что CSRF_COOKIE_HTTPONLY настроен на False в ваших settings.py!

 Смежные вопросы

  • Нет связанных вопросов^_^