Из-за изменения CSRF-политики для запросов AJAX, начиная с Django 1.2.5, все реализации Uploadify, похоже, не работают. Есть несколько попыток и довольно размытые ответы, но пока нет решения. Единственный обходной путь сейчас, кажется, использует декоратор @csrf_exempt, как указано в этом посте: Исправление ошибки django csrf при использовании uploadify
Несмотря на то, что Пол Макмиллан указал причину этой проблемы, он не предложил решения этой проблемы (кроме изучения ActionScript и переписывания Uploadify). Для тех, кто использует Django и jQuery, было бы интересно немного подробнее разобраться в этой теме, так как не у всех есть время на изучение actionScript. Мне особенно любопытно, если бы было решение, использующее опцию script-data 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
});
Middleware:
#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?
Что я, по сути, хотел сказать: не устанавливайте «бисквит» вслепую, но после проверки важных значений (csrfmiddlewaretoken, sessionid, что еще?). Я думаю, что это может сработать, хотя я не уверен, что полностью понял механизм защиты csrf ...