Как включить токен CSRF Django 1.2 в HTML-форму, сгенерированную Javascript?
недавно я обновился до Django 1.2.3, и мои формы загрузки теперь сломаны. Всякий раз, когда я пытаюсь загрузить, я получаю " сбой проверки CSRF. Запрос прерван." сообщение об ошибке.
после прочтения документация Django по этому вопросу говорится, что мне нужно добавить тег шаблона {% csrf_token %} в HTML <form>
в моем шаблоне. К сожалению, мой <form>
генерируется с помощью JavaScript (в частности, свойство "html" ExtJs на Панель.)
короче говоря, как добавить требуемый тег токена CSRF в мой <form>
когда моя <form>
не входит в шаблон Django?
6 ответов
другой вариант-адаптировать решение на основе cookie / заголовка, показанное в документы Django С Ext-предпочтительнее, если у вас много шаблонов и вы не хотите менять каждый из них.
просто поместите следующий фрагмент в переопределения.js (или везде, где вы ставите глобальные модификации):
Ext.Ajax.on('beforerequest', function (conn, options) {
if (!(/^http:.*/.test(options.url) || /^https:.*/.test(options.url))) {
if (typeof(options.headers) == "undefined") {
options.headers = {'X-CSRFToken': Ext.util.Cookies.get('csrftoken')};
} else {
options.headers.extend({'X-CSRFToken': Ext.util.Cookies.get('csrftoken')});
}
}
}, this);
(edit: Ext уже имеет функцию чтения файлов cookie, нет необходимости дублировать его)
самый простой способ-создать скрытую форму на Вашей странице с помощью django, которая ничего не делает. Затем используйте JavaScript для извлечения формы и, в частности, ввода токена из формы. Наконец, вставьте или скопируйте этот токен в форму, которую вы динамически генерируете.
вот два примера того, как вы можете опубликовать токен для JavaScript.
<input id="csrf_token" value="{{ csrf_token }}"/>
<script type="text/javascript">
var CSRF_TOKEN = document.getElementById('csrf_token').value;
</script>
или
<script type="text/javascript">
var CSRF_TOKEN = "{{ csrf_token }}";
</script>
лучшим решением является создание кода JS-файла из представления / шаблона.
затем в представлении вы можете установить токен csrf в контексте, например...
from django.core.context_processors import csrf
context = RequestContext(request)
context.update(csrf(request))
затем, в шаблоне можно использовать {{ csrf_token }}
чтобы получить необработанное значение токена csrf, а затем использовать его для создания скрытого поля в вашей форме с именем csrfmiddlewaretoken
.
делает вида POST
ing также ответить на GET
? В этом JS-код может сделать GET
запрос к рассматриваемому представлению и анализ выходных данных для извлечения маркера CSRF. Мой JS-fu слаб, и я не уверен, как лучше всего вы можете сделать разбор со стороны клиента.
на широкое обзоры пример см. этот вопрос. В этом случае пользователь пытался POST
использование скрипта Python и сбой по той же причине. Решение было то же самое, кроме того, что он должен был сделать это из скрипта Python, а не JavaScript.
это может быть не идеально, но это было самое быстрое решение для меня. В моем основном шаблоне в нижней части "тела" я добавил функцию javascript в свою библиотеку.
<script type="text/javascript">
MyToolkit.Utils.getCSRFToken = function () {
return "{% csrf_token %}";
};
</script>
Это будет использовать токен csrf или автоматически генерировать новый, если это необходимо. Он будет обрабатывать все формы, представленные на странице. Если у вас есть формы вне сайта, Вам нужно убедиться, что они не запускают этот код.
<script>
$(document).on('submit', 'form[method=post]', function(){
if(!document.cookie.match('csrftoken=([a-zA-Z0-9]{32})')) {
for(var c = ''; c.length < 32;) c += 'abcdefghijklmnopqrstuvwxyz'.charAt(Math.random() * 26)
document.cookie = 'csrftoken=' + c + '; path=/'
}
if(!this.csrfmiddlewaretoken) $(this).append('<input type="hidden" name="csrfmiddlewaretoken">')
$(this.csrfmiddlewaretoken).val(document.cookie.match('csrftoken=([a-zA-Z0-9]{32})')[1])
})
</script>
требуется jQuery 1.7+