2012-05-01 37 views
6

我使用djangockeditor爲TextEdits提供wysiwyg的味道。我想使用CKEditor文件上傳功能(在文件瀏覽器/圖像對話框中),但CKEditor上傳圖像的POST只包含文件數據。如何在CKeditor上傳中添加一個字段到POST值

這是CSRF檢查的問題。我無法在CKEditor文檔中找到並找到一處去更改文件上傳的POST數據,以在POST數據中添加django的csrf_token。

作爲解決方法,我可以更改filebrowserUploadUrl參數以在上載URL中包含csrf數據,使用@csrf_exempt作爲上傳視圖,並檢查request.GET參數以檢查csrf。但是這個解決方案安全嗎?

無論如何,如果有人知道如何令牌直接包含CKEditor的文件上傳POST數據中CSRF,我很濃厚的興趣......

+0

你使用[django-ckeditor](http://pypi.python.org/pypi/django-ckeditor)或其他小部件?如果你是自己寫的 - 這是正確的,你不能添加一些東西,因爲張貼的主體是文件本身。所以是的,你需要在url參數中提供令牌。 – ilvar

+0

甚至Django的CKEditor的不使用文件上傳CSRF保護(這是壞恕我直言):@csrf_exempt高清上傳(請求): 「」」 上傳文件和URL發送回的CKEditor TODO: 驗證上傳 「」「 – jmbarbier

回答

5

可以爲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

哇,對舊問題的新鮮迴應:-)謝謝!! ...您的方式遠比我的黑客入侵ckeditor代碼更清潔。下次我將嘗試使用ckeditor。 – jmbarbier

+0

我得到: 「Uncaught TypeError:無法讀取屬性'getContentElement'null」 我在想什麼? – Mladen

1

看來,有沒有辦法不修改數據添加到CKEditor的上傳數據ckeditor源代碼。要修改的源代碼是ckeditor 3.6.2中第1440行的plugins/dialogui/plugin.js,其中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>', 

現在我們可以安全使用上傳CKEditor的使用Django

2

發送到服務器的額外數據通過get請求傳遞。我試圖增加額外的數據,並最終實現這一目標增加了一個用於發送數據

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    
       */ 

    } 
    }); 
1

通過的CKEditor爲埃爾格集成圖像上傳時,我經歷了類似的問題形式的URL參數。我想出了侵入性最小的解決方案是綁定到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&params=1'; 


       if (onClick && onClick.call(evt.sender, evt) === false) { 
         return false; 
       } 

       return true; 
      }; 
     } 
    } 
}); 
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; 
}); 
+0

無法使用默認的FileBrowser上傳:http://stackoverflow.com/questions/34851158/ckeditor-4-5-fileuploadrequest-event-not-firing –

0

爲您提供跨HTTPS發送CSFR令牌的URL應該是確定要做到這一點(從一個安全品脫),也輕鬆了許多處理。

假設django可以讀取該變量,或者您可以輕鬆地修改django。這些試圖改變CKeditor的答案似乎有點過分。

只要您的CSFR_token由用戶瀏覽器以安全的方式發送到服務器,無論是通過POST還是GET都無關緊要。遊戲中的安全問題是處於中間攻擊的人,即您不希望以明文形式廣播用戶CSFR_token。

嚴格來說,這種數據應該根據HTTP規範以POST的形式發送,但這似乎是'濫用'GET協議可能是可以接受的情況,因爲您無法特別控制CKEditor代碼優雅的方式。

如果CKEditor在升級中更改內容,通過URL傳遞令牌將始終有效,您也可能被抓到。

相關問題