Из-за изменения политики CSRF для запросов AJAX, начиная с Django 1.2.5, все реализации Uploadify кажутся неработоспособными. Есть несколько попыток и некоторые довольно размытые ответы, но решения пока нет. Единственный обходной путь прямо сейчас, кажется, использует декоратор @csrf_exempt, как указано в этом сообщении: uploadify">Исправление ошибки django csrf при использовании uploadify
Несмотря на то, что Пол Макмиллан указал на причину этой проблемы, он не предложил ее решения (кроме изучения ActionScript и переписывания Uploadify). Для тех, кто использует Django и jQuery, было бы интересно получить более конкретную информацию по этой теме, так как не у всех есть время для изучения ActionScript. Мне особенно любопытно, может ли быть решение, использующее параметр данных сценария Uploadify, который я не мог заставить работать.
$('#fileInput').uploadify({
'uploader' : '{{ uploadify_path }}uploadify.swf',
'script' : '{% url uploadify_upload %}',
//this is the interesting line
'scriptData': {"CSRF-Token" : $('input[name="csrfmiddlewaretoken"]').val()}
},
'cancelImg' : '{{ uploadify_path }}cancel.png',
'auto' : false,
'folder' : '{{ upload_path }}',
'multi' : true,
'onAllComplete' : allComplete
});
Я думал, что это может сработать, данные, указанные в опции script-data, действительно появляются в запросе.POST dict. Я проверяю это с помощью pdb и ищу запрос:
@csrf_exempt
def upload(request, *args, **kwargs):
if request.method == 'POST':
if request.FILES:
upload_received.send(sender='uploadify', data=request.FILES['Filedata'])
import pdb; pdb.set_trace();
return HttpResponse(request)
И это результат:
<WSGIRequest
GET:<QueryDict: {}>,
POST:<QueryDict: {u'CSRF-Token': [u'de885c962f9a2e50fec140e161ca993e'], u'folder': [u'/static/uploads/'], u'Upload': [u'Submit Query'], u'Filename': [u'P4010040.JPG']}>,
COOKIES:{},
META:{'App
and so on, the rest as expected
Это почти то же решение, что было предложено в ответе на ранее упомянутый пост, но это решение нарушит CSRF-защиту. Могу ли я как-то использовать scriptData для прохождения CSRF-валидации, не нарушая защиты? Какая информация мне понадобится для прохождения проверки и как я могу ее использовать?
изменить:
В сообщении, которое я упомянул, используется это решение, которое нарушает защиту csrf:
Javascript:
biscuit = document.cookie;
csrt = $('input[name="csrfmiddlewaretoken"]').val();
$('#file_upload').uploadify({
// pass the cookie and the csrftoken
scriptData : {biscuit: biscuit, csrfmiddlewaretoken: csrf},
.... // other codes
});
Промежуточное ПО:
#insert after: 'django.middleware.common.CommonMiddleware'
def process_request(self, request):
if (request.method == 'POST'):
if request.POST.has_key('biscuit'):
biscuit = request.POST['biscuit']
tmp = map(lambda x: tuple(x.split("=")), biscuit.split(" "))
# set a cookie
request.COOKIES.update(tmp)
Что, если бы была прямая проверка правильности значений csrfmiddlewaretoken и session_id? Основная проблема заключается в том, что защита Djangos CSRF полагается на файл cookie CSRF, а uploadify не передает файл cookie. Но он может передавать значения csrfmiddlewaretoken и session_id через scriptData. Разве это не сохранит защиту CSRF, говоря Django не искать csrf-cookie, а соответствующие значения внутри request.POST?
Что я хотел сказать по сути: устанавливайте "biscuit" не вслепую, а после проверки важных значений (csrfmiddlewaretoken, sessionid, что еще?). Я думаю, что это может сработать, хотя я не уверен, что полностью понял механизм защиты csrf...