How to add a field to POST values in CKeditor upload

二次信任 提交于 2019-11-29 14:21:21

问题


I use django and ckeditor to provide wysiwyg taste to TextEdits. I would like to use CKEditor file upload function (in filebrowser / image dialog), but the POST made by CKEditor to upload the image just contains the file data.

This is a problem for CSRF checking. I couldn't find in CKEditor documentation and source a place to change the POST data for file upload, to add django's csrf_token in POST data.

As a workaround, I can change the filebrowserUploadUrl parameters to include csrf data in upload URL, use the @csrf_exempt for the upload view, and check request.GET parameters to check csrf. But is this solution safe ?

Anyway, if somebody knows how to include csrf token directly within CKEditor file upload POST data, i'm strongly interested...


回答1:


You can register for the dialogDefinition event, and completely rewrite the upload tab, thus:

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

This is an untested simplification of my real-world version, but hopefully it shows the idea.

This does not set the URL field in the image dialog, so clicking OK on the dialog will give you an error message. You will need to set that on a successful upload, thus:

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



回答2:


The extra data sent to the server is passed by get request. I was trying to add extra data and finally achieve this adding to a url parameters of the form that is used to send data

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

     }
   });



回答3:


It seems that there is no way to add data to ckeditor upload data without editing ckeditor source code. The source code to be modified is plugins/dialogui/plugin.js, around lines 1440 in ckeditor 3.6.2, where ckeditor creates the form used by the upload 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>',

And now we can use safely upload in ckeditor with django




回答4:


I experienced a similar problem when integrating image uploading through CKEditor for Elgg. The least intrusive solution I came up with was to bind to the onClick event for the submit button and modify the form directly from that:

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



回答5:


The question is too old but...

Version 4.5 you can add hook into any request

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



回答6:


Providing you are sending a CSFR token in the URL across HTTPS it should be ok to do that (from a security pint of view) and also a lot easier to deal with.

That assumes django can read that variable or you are able to easily mod django. These answers trying to alter CKeditor seem a bit too much work imo.

As long as your CSFR_token is being sent by the users browser in a secure way to the server it doesn't matter if it is via POST or GET. The security concern at play is a man in the middle attack, i.e you don't want a users CSFR_token being broadcast in plain text.

Strictly speaking this kind of data should be sent as POST according to the HTTP spec but this seems like a situation where 'misusing' the GET protocol might be acceptable as you don't have control of the CKEditor code in a particularly elegant way.

Also you could get caught out if CKEditor changes things in an upgrade, passing the token via the URL will always work.



来源:https://stackoverflow.com/questions/10392582/how-to-add-a-field-to-post-values-in-ckeditor-upload

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!