2012-05-01 58 views
6

Tôi sử dụng djangockeditor để cung cấp hương vị wysiwyg cho TextEdits. Tôi muốn sử dụng chức năng tải lên tệp CKEditor (trong hộp thoại filebrowser/image), nhưng POST được thực hiện bởi CKEditor để tải lên hình ảnh chỉ chứa dữ liệu tệp.Cách thêm trường vào giá trị POST trong tệp Công cụ chỉnh sửa tải lên

Đây là vấn đề khi kiểm tra CSRF. Tôi không thể tìm thấy trong tài liệu CKEditor và nguồn một nơi để thay đổi dữ liệu POST cho tải lên tệp, để thêm csrf_token của django trong dữ liệu POST.

Như một giải pháp thay thế, tôi có thể thay đổi thông số FilloadowserUploadUrl để bao gồm dữ liệu csrf trong URL tải lên, sử dụng @csrf_exempt cho chế độ xem tải lên và kiểm tra tham số request.GET để kiểm tra csrf. Nhưng giải pháp này có an toàn không?

Dù sao, nếu ai đó biết làm thế nào để bao gồm CSRF thẻ trực tiếp trong ckeditor dữ liệu tập tin tải lên POST, tôi mạnh mẽ quan tâm ...

+0

Bạn đang sử dụng [django-ckeditor] (http://pypi.python.org/pypi/django-ckeditor) hoặc một tiện ích con khác? Nếu bạn đang viết nó một mình - đó là chính xác, bạn không thể thêm một cái gì đó để POST vì cơ thể được đăng là tập tin chính nó. Vì vậy, có, bạn cần cung cấp mã thông báo trong thông số url. – ilvar

+0

thậm chí django-ckeditor không sử dụng bảo vệ CSRF cho tập tin tải lên (và đây là IMHO xấu): @csrf_exempt def tải lên (theo yêu cầu): """ cập nhật một tập tin và gửi lại URL của mình cho ckeditor TODO:. Xác nhận tải lên "" " – jmbarbier

Trả lời

5

Bạn có thể đăng ký tham gia sự kiện dialogDefinition, và hoàn toàn viết lại tab upload, như sau:

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>' 
     }] 
    }); 
    } 
}); 

Đây là một chưa được kiểm tra đơn giản hóa phiên bản thế giới thực của tôi, nhưng hy vọng nó cho thấy ý tưởng.

Điều này không đặt trường URL trong hộp thoại hình ảnh, do đó nhấp vào OK trên hộp thoại sẽ cung cấp cho bạn thông báo lỗi. Bạn sẽ cần phải đặt điều đó khi tải lên thành công, do đó:

CKEDITOR.dialog.getCurrent().getContentElement('info', 'txtUrl').setValue(theURL); 
+1

Wow, phản hồi mới cho câu hỏi cũ :-) cảm ơn !! ... cách của bạn sạch hơn rất nhiều so với việc hack vào mã ckeditor. Tôi sẽ cố gắng theo cách của bạn thời gian tới tôi sẽ phải sử dụng ckeditor. – jmbarbier

+0

Tôi nhận được: "Loại lỗi không xác định: Không thể đọc thuộc tính 'getContentElement' của null" Tôi thiếu gì? – Mladen

1

Dường như không có cách nào để thêm dữ liệu vào dữ liệu ckeditor upload mà không cần chỉnh sửa mã nguồn ckeditor. Mã nguồn được sửa đổi là plugins/dialogui/plugin.js, xung quanh dòng 1440 trong ckeditor 3.6.2, trong đó ckeditor tạo biểu mẫu được sử dụng bởi iframe tải lên.

// 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>', 

Và bây giờ chúng ta có thể sử dụng một cách an toàn tải lên trong ckeditor với django

2

Dữ liệu bổ sung được gửi đến máy chủ được chuyển bằng cách nhận yêu cầu. Tôi đã cố gắng bổ sung thêm dữ liệu và cuối cùng đạt được điều này thêm vào một tham số url của hình thức được sử dụng để gửi dữ liệu

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

tôi gặp phải vấn đề tương tự khi tích hợp hình ảnh tải lên thông qua ckeditor cho Elgg. Các giải pháp xâm nhập ít nhất tôi đã đưa ra là để ràng buộc với sự kiện onClick cho nút gửi và sửa đổi các hình thức trực tiếp từ rằng:

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

Câu hỏi đặt ra là quá cũ nhưng ...

Version 4.5 bạn có thể thêm móc vào bất kỳ yêu cầu nào

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

Không hoạt động với trình tải lên FileBrowser mặc định: http://stackoverflow.com/questions/34851158/ckeditor-4-5-fileuploadrequest-event-not-firing –

0

Cho phép bạn gửi mã thông báo CSFR trong URL qua HTTPS, bạn có thể làm điều đó (từ chế độ xem bảo mật) và cũng dễ xử lý hơn nhiều.

Điều đó giả định django có thể đọc biến đó hoặc bạn có thể dễ dàng mod django. Những câu trả lời cố gắng để thay đổi CKeditor có vẻ hơi quá nhiều công việc.

Miễn là CSFR_token của bạn đang được gửi bởi trình duyệt người dùng một cách an toàn đến máy chủ, điều đó không quan trọng nếu đó là thông qua POST hoặc GET. Mối quan tâm về bảo mật khi chơi là một người đàn ông trong cuộc tấn công trung gian, tức là bạn không muốn một người dùng CSFR_token được phát sóng bằng văn bản thuần túy.

Nói đúng loại dữ liệu này sẽ được gửi dưới dạng POST theo thông số HTTP nhưng điều này có vẻ như là tình huống 'lạm dụng' giao thức GET có thể chấp nhận được vì bạn không có quyền kiểm soát mã CKEditor cách thanh lịch.

Bạn cũng có thể bị bắt nếu CKEditor thay đổi mọi thứ trong bản nâng cấp, chuyển mã thông báo qua URL sẽ luôn hoạt động.

Các vấn đề liên quan