【发布时间】:2011-08-10 12:59:06
【问题描述】:
由于自 Django 1.2.5 以来 AJAX 请求的 CSRF 策略发生了变化,Uploadify 的所有实现似乎都被破坏了。有一些尝试和一些相当模糊的答案,但还没有解决方案。现在唯一的解决方法似乎是使用 @csrf_exempt 装饰器,正如这篇文章中指出的那样:Fixing django csrf error when using uploadify
虽然 Paul McMillan 指出了这个问题的原因,但他并没有提出解决方案(除了学习 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 选项中指定的数据确实出现在 request.POST 字典中。我用 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 的正确值怎么办?主要问题是 Django 的 CSRF 保护依赖于 CSRF cookie,并且 uploadify 不通过 cookie。但它可以通过 scriptData 传递 csrfmiddlewaretoken 和 session_id 的值。它不会保留 CSRF 保护,告诉 Django 不要查找 csrf-cookie,而是查找 request.POST 中的相关值吗?
我本质上想说的是:不要盲目设置“饼干”,而是在检查重要值(csrfmiddlewaretoken,sessionid,还有什么?)之后。我认为这可行,尽管我不确定我是否完全理解 csrf 保护的机制......
【问题讨论】:
-
我很想为此找到一个好的解决方案!只需花 5 个小时尝试,没有任何效果。