Я мог бы использовать некоторую помощь в соответствии с механизмом защиты CSRF в Django через мой пост AJAX. Я следовал инструкциям здесь:
http://docs.djangoproject.com/en/dev/ref/contrib/csrf/
Я скопировал пример кода AJAX, который есть на этой странице:
http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
Я помещаю предупреждение, распечатывающее содержимое getCookie('csrftoken')
перед xhr.setRequestHeader
вызовом, и оно действительно заполнено некоторыми данными. Я не уверен, как проверить правильность токена, но я воодушевлен тем, что он что-то находит и отправляет.
Но Django по-прежнему отвергает мой пост AJAX.
Вот мой JavaScript:
$.post("/memorize/", data, function (result) {
if (result != "failure") {
get_random_card();
}
else {
alert("Failed to save card data.");
}
});
Вот ошибка, которую я вижу от Джанго:
[23 / Feb / 2011 22:08:29] «POST / memorize / HTTP / 1.1» 403 2332
Я уверен, что что-то упустил, и, возможно, это просто, но я не знаю, что это. Я искал вокруг SO и увидел некоторую информацию об отключении проверки CSRF для моего просмотра черезcsrf_exempt
декоратор, но я нахожу это непривлекательным. Я попробовал это, и это работает, но я бы предпочел, чтобы мой POST работал так, как Django рассчитывал ожидать, если это возможно.
На всякий случай это полезно, вот суть того, что делает мой взгляд:
def myview(request):
profile = request.user.profile
if request.method == 'POST':
"""
Process the post...
"""
return HttpResponseRedirect('/memorize/')
else: # request.method == 'GET'
ajax = request.GET.has_key('ajax')
"""
Some irrelevent code...
"""
if ajax:
response = HttpResponse()
profile.get_stack_json(response)
return response
else:
"""
Get data to send along with the content of the page.
"""
return render_to_response('memorize/memorize.html',
""" My data """
context_instance=RequestContext(request))
Спасибо за ваши ответы!
Ответы:
Реальное решение
Хорошо, мне удалось отследить проблему. Он лежит в коде Javascript (как я предложил ниже).
Что вам нужно, это:
вместо кода, опубликованного в официальных документах: https://docs.djangoproject.com/en/2.2/ref/csrf/
Рабочий код взят из этой записи Django: http://www.djangoproject.com/weblog/2011/feb/08/security/
Таким образом, общее решение: «использовать обработчик ajaxSetup вместо обработчика ajaxSend». Я не знаю, почему это работает. Но у меня это работает :)
Предыдущий пост (без ответа)
Я испытываю ту же проблему на самом деле.
Это происходит после обновления до Django 1.2.5 - в Django 1.2.4 не было ошибок с запросами AJAX POST (AJAX не был защищен каким-либо образом, но работал нормально).
Как и OP, я попробовал фрагмент JavaScript, размещенный в документации Django. Я использую jQuery 1.5. Я также использую промежуточное программное обеспечение "django.middleware.csrf.CsrfViewMiddleware".
Я попытался следовать коду промежуточного программного обеспечения, и я знаю, что это терпит неудачу на этом:
а потом
это "если" верно, потому что "request_csrf_token" пусто.
В основном это означает, что заголовок НЕ установлен. Так что-нибудь не так с этой строкой JS:
?
Я надеюсь, что предоставленные детали помогут нам в решении проблемы :)
источник
ajaxSetup
а неajaxSend
противоречит документам jQuery: api.jquery.com/jQuery.ajaxSetupЕсли вы используете
$.ajax
функцию, вы можете просто добавитьcsrf
токен в теле данных:источник
<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
csrfmiddlewaretoken: '{{ csrf_token }}'
в свойdata
словарь в$.post
вызове.Добавьте эту строку в ваш код JQuery:
и сделано.
источник
CSRF Failed: CSRF token missing or incorrect.
Проблема в том, что django ожидает, что значение из cookie будет передано обратно как часть данных формы. Код из предыдущего ответа заставляет javascript выискивать значение cookie и помещать его в данные формы. Это прекрасный способ сделать это с технической точки зрения, но он выглядит немного многословно.
В прошлом я делал это проще, получая JavaScript, чтобы поместить значение токена в данные поста.
Если вы используете {% csrf_token%} в своем шаблоне, вы получите скрытое поле формы, содержащее значение. Но, если вы используете {{csrf_token}}, вы просто получите чистое значение токена, так что вы можете использовать это в javascript, как это ....
Затем вы можете включить это с требуемым именем ключа в хеш, который вы затем отправляете как данные для вызова ajax.
источник
window
объекте, чтобы впоследствии они были доступны. Даже в статических файлах.{% csrf_token %}
Положить в HTML шаблоны внутри<form></form>
переводит что-то вроде:
так почему бы просто не выполнить поиск в вашем JS следующим образом:
и затем передайте его, например, делая POST, например:
источник
Ответ не на вопросы:
использование:
источник
Если ваша форма правильно публикуется в Django без JS, вы сможете постепенно расширять ее с помощью ajax без какого-либо взлома или беспорядочной передачи токена csrf. Просто сериализуйте всю форму, и она автоматически выберет все поля формы, включая скрытое поле csrf:
Я тестировал это с Django 1.3+ и jQuery 1.5+. Очевидно, это будет работать для любой формы HTML, а не только для приложений Django.
источник
Используйте Firefox с Firebug. Откройте вкладку «Консоль» во время запуска AJAX-запроса. С ним
DEBUG=True
вы получите красивую страницу ошибок django в качестве ответа, и вы даже сможете увидеть визуализированный html-ответ ajax на вкладке консоли.Тогда вы будете знать, в чем ошибка.
источник
Принято, скорее всего, красная сельдь. Разница между Django 1.2.4 и 1.2.5 заключалась в требовании токена CSRF для запросов AJAX.
Я столкнулся с этой проблемой на Django 1.3, и это было вызвано тем, что файл cookie CSRF не был установлен в первую очередь. Django не будет устанавливать куки, если это не нужно. Таким образом, сайт исключительно или с большим количеством ajax, работающий на Django 1.2.4, потенциально никогда бы не отправил токен клиенту, и тогда обновление, требующее токен, вызовет ошибки 403.
Идеальное решение здесь: http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#page-uses-ajax-without-any-html-form,
но вам придется подождать 1.4, если только это просто документирование кода
редактировать
Также обратите внимание, что более поздние документы Django отмечают ошибку в jQuery 1.5, поэтому убедитесь, что вы используете 1.5.1 или более позднюю версию с предлагаемым кодом Django: http://docs.djangoproject.com/en/1.3/ref/contrib/csrf/# Аякса
источник
ensure_csrf_cookie
, который можно обернуть вокруг представления, чтобы убедиться, что он отправляет cookie.csrftoken
столкнулся, во-первых, нет файлов cookie, спасибо!Кажется, никто не упомянул, как сделать это в чистом JS, используя
X-CSRFToken
заголовок, и{{ csrf_token }}
вот простое решение, в котором вам не нужно искать файлы cookie или DOM:источник
Как нигде в текущих ответах не указано, самое быстрое решение, если вы не встраиваете js в шаблон:
Поместите
<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
перед ссылкой на файл script.js в своем шаблоне, затем добавьтеcsrfmiddlewaretoken
в свойdata
словарь в своем файле js:источник
Я только что столкнулся с немного другой, но похожей ситуацией. Не уверен на 100%, будет ли это решением для вашего случая, но я решил проблему для Django 1.3, установив параметр POST 'csrfmiddlewaretoken' с правильной строкой значения cookie, которая обычно возвращается в виде вашего домашнего HTML Django система шаблонов с тегом {% csrf_token%}. Я не примерял более старый Django, просто получилось и решил Django1.3. Моя проблема заключалась в том, что первый запрос, отправленный через Ajax из формы, был успешно выполнен, но вторая попытка с точно такой же ошибкой привела к состоянию 403, даже если заголовок 'X-CSRFToken' правильно размещен со значением токена CSRF. как и в случае с первой попытки. Надеюсь это поможет.
С Уважением,
Хиро
источник
Вы можете вставить этот JS в ваш HTML-файл, не забудьте поставить его перед другой функцией JS
источник
Один токен CSRF присваивается каждому сеансу (т. Е. При каждом входе в систему). Поэтому, прежде чем вы захотите получить некоторые данные, введенные пользователем, и отправить их как вызов ajax какой-либо функции, защищенной декоратором csrf_protect, попробуйте найти функции, которые вызываются, прежде чем вы получите эти данные от пользователя. Например, должен отображаться шаблон, по которому ваш пользователь вводит данные. Этот шаблон обрабатывается какой-то функцией. В этой функции вы можете получить токен csrf следующим образом: csrf = request.COOKIES ['csrftoken'] Теперь передайте это значение csrf в контекстном словаре, для которого отображается соответствующий шаблон. Теперь в этом шаблоне напишите следующую строку: Теперь в вашей функции javascript перед выполнением ajax-запроса напишите это: var csrf = $ ('# csrf'). val () это выберет значение токена, переданного в шаблон, и сохранит его в переменной csrf. Теперь во время вызова ajax в ваших данных поста также передайте это значение: "csrfmiddlewaretoken": csrf
Это будет работать, даже если вы не используете формы django.
Фактически, логика здесь такова: вам нужен токен, который вы можете получить из запроса. Поэтому вам просто нужно выяснить, какая функция вызывается сразу после входа в систему. Получив этот токен, либо сделайте еще один вызов ajax, чтобы получить его, либо передайте его какому-нибудь шаблону, доступному вашему ajax.
источник
csrftoken: csrftoken
вместоcsrfmiddlwaretoken: csrftoken
. После смены все заработало. Спасибодля тех, кто сталкивается с этим и пытается отладить:
1) проверка django csrf (если вы ее отправляете) здесь
2) В моем случае
settings.CSRF_HEADER_NAME
было установлено значение «HTTP_X_CSRFTOKEN», и мой вызов AJAX отправлял заголовок с именем «HTTP_X_CSRF_TOKEN», поэтому все не работало. Я мог бы либо изменить его в вызове AJAX, либо в настройке django.3) Если вы решите изменить его на стороне сервера, найдите место установки django и добавьте
csrf middleware
точку останова в .f, которую вы используетеvirtualenv
, это будет что-то вроде:~/.envs/my-project/lib/python2.7/site-packages/django/middleware/csrf.py
Затем убедитесь, что
csrf
токен правильно получен из запроса.4) Если вам нужно изменить заголовок и т. Д., Измените эту переменную в файле настроек
источник
Если кто-то борется с axios, чтобы сделать эту работу, это помогло мне:
Источник: https://cbuelter.wordpress.com/2017/04/10/django-csrf-with-axios/
источник
В моем случае проблема была в конфигурации nginx, которую я скопировал с основного сервера на временный с отключением https, который не нужен на втором процессе.
Мне пришлось закомментировать эти две строки в конфиге, чтобы он снова заработал:
источник
Вот менее подробное решение, предоставленное Django:
Источник: https://docs.djangoproject.com/en/1.11/ref/csrf/
источник