我使用 django 和 ckeditor 为TextEdits提供了所见即所得。我想使用CKEditor文件上传功能(在文件浏览器/图像对话框中),但是CKEditor发布的上传图像的POST只包含文件数据。
这是CSRF检查的问题。我在CKEditor文档中找不到并找到更改文件上传的POST数据的地方,在POST数据中添加django的csrf_token。
作为一种解决方法,我可以更改filebrowserUploadUrl参数以在上传URL中包含csrf数据,使用@csrf_exempt作为上传视图,并检查request.GET参数以检查csrf。但这个解决方案安全吗?
无论如何,如果有人知道如何在CKEditor文件上传POST数据中直接包含csrf令牌,我非常感兴趣......
答案 0 :(得分:7)
您可以注册dialogDefinition事件,并完全重写上传选项卡,因此:
CKEDITOR.on('dialogDefinition', function (ev) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if (dialogName == 'image') {
dialogDefinition.removeContents('Upload');
dialogDefinition.addContents({
title: "Upload",
id: "upload",
label: "Upload",
elements: [{
type: "html",
html: '<form><input id="imageupload" type="file" name="files[]" />{%csrf_token%}</form>'
}]
});
}
});
这是对我的真实版本的一种未经测试的简化,但希望它显示出这个想法。
这不会在图像对话框中设置URL字段,因此单击对话框上的“确定”将显示错误消息。您需要在成功上传时设置,因此:
CKEDITOR.dialog.getCurrent().getContentElement('info', 'txtUrl').setValue(theURL);
答案 1 :(得分:2)
发送到服务器的额外数据由get请求传递。我试图添加额外的数据,最后实现这个添加到用于发送数据的表单的url参数
CKEDITOR.on('dialogDefinition', function(ev)
{
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if (dialogName == 'image')
{
dialogDefinition.contents[2].elements[0].action += '&pin=123456';
/* 2 is the upload tab it have two elements 0=apparently is the
and 1: is the button to perform the upload, in 0 have the action property with the parameters of the get request simply adding the new data
*/
}
});
答案 2 :(得分:1)
似乎没有办法在不编辑ckeditor源代码的情况下将数据添加到ckeditor上传数据。要修改的源代码是plugins / dialogui / plugin.js,围绕ckeditor 3.6.2中的第1440行,其中ckeditor创建上传iframe使用的表单。
// ADDED TO CKEDITOR CODE %<
var csrfitems = document.getElementsByName("csrfmiddlewaretoken")
var csrftoken = ""
if(csrfitems.length > 0)
csrftoken = csrfitems[0].value
// >% END OF ADDED CODE
if ( elementDefinition.size )
size = elementDefinition.size - ( CKEDITOR.env.ie ? 7 : 0 ); // "Browse" button is bigger in IE.
frameDocument.$.write( [ '<html dir="' + langDir + '" lang="' + langCode + '"><head><title></title></head><body style="margin: 0; overflow: hidden; background: transparent;">',
'<form enctype="multipart/form-data" method="POST" dir="' + langDir + '" lang="' + langCode + '" action="',
CKEDITOR.tools.htmlEncode( elementDefinition.action ),
'">',
// ADDED TO CKEDITOR CODE
'<input type="hidden" name="csrfmiddlewaretoken" value="',csrftoken,'"/>',
// >% END OF ADDED CODE
'<input type="file" name="',
CKEDITOR.tools.htmlEncode( elementDefinition.id || 'cke_upload' ),
'" size="',
CKEDITOR.tools.htmlEncode( size > 0 ? size : "" ),
'" />',
'</form>',
现在我们可以使用django
在ckeditor中安全上传答案 3 :(得分:1)
在通过CKEditor为Elgg集成图像上传时,我遇到了类似的问题。我提出的最少侵入性的解决方案是绑定到提交按钮的onClick事件,并直接从中修改表单:
CKEDITOR.on('dialogDefinition', function (ev) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if (dialogName === 'image') {
var uploadTab = dialogDefinition.getContents('Upload');
for (var i = 0; i < uploadTab.elements.length; i++) {
var el = uploadTab.elements[i];
if (el.type !== 'fileButton') {
continue;
}
// add onClick for submit button to add inputs or rewrite the URL
var onClick = el.onclick;
el.onClick = function(evt) {
var dialog = this.getDialog();
var fb = dialog.getContentElement(this['for'][0], this['for'][1]);
var action = fb.getAction();
var editor = dialog.getParentEditor();
editor._.filebrowserSe = this;
// if using jQuery
$(fb.getInputElement().getParent().$).append('<input type="hidden" name="foo" value="bar">');
// modifying the URL
fb.getInputElement().getParent().$.action = '/my/new/action?with&query¶ms=1';
if (onClick && onClick.call(evt.sender, evt) === false) {
return false;
}
return true;
};
}
}
});
答案 4 :(得分:1)
这个问题太旧了,但是......
版本4.5你可以在任何请求中添加钩子
editor.on( 'fileUploadRequest', function( evt ) {
var xhr = evt.data.fileLoader.xhr;
xhr.setRequestHeader( 'Cache-Control', 'no-cache' );
xhr.setRequestHeader( 'csrf header ', 'HEADER' );
xhr.withCredentials = true;
} );
答案 5 :(得分:0)
假设您正在通过HTTPS在URL中发送CSFR令牌,那么应该可以(从安全品种的角度来看)并且更容易处理。
假设django可以读取该变量,或者您可以轻松地修改django。试图改变CKeditor的这些答案似乎有点太多了。
只要您的CSFR_token由用户浏览器以安全的方式发送到服务器,如果是通过POST或GET,则无关紧要。游戏中的安全问题是中间人攻击,即你不希望用纯文本广播用户CSFR_token。
严格来说,根据HTTP规范,这类数据应该作为POST发送,但这似乎是一种滥用&#39; GET协议可能是可以接受的,因为您无法以特别优雅的方式控制CKEditor代码。
如果CKEditor在升级中更改了内容,您也可能会被抓住,通过URL传递令牌将始终有效。