2012-05-01 20 views
6

utilizo Django y CKEditor para proporcionar sabor a TextEdits WYSIWYG. Me gustaría utilizar la función de carga de archivos CKEditor (en el cuadro de diálogo archivo de archivos/imágenes), pero la POST realizada por CKEditor para cargar la imagen solo contiene los datos del archivo.Cómo agregar un campo a POST valores en CKeditor cargar

Este es un problema para la comprobación de CSRF. No pude encontrar en la documentación de CKEditor y obtener un lugar para cambiar los datos POST para cargar archivos, para agregar csrf_token de django en datos POST.

Como solución alternativa, puedo cambiar los parámetros filebrowserUploadUrl para incluir datos de csrf en la carga de URL, usar @csrf_exempt para la vista de carga y verificar los parámetros request.GET para verificar csrf. Pero, ¿esta solución es segura?

De todos modos, si alguien sabe cómo incluir csrf señal directamente en los datos POST de carga de archivos CKeditor, estoy muy interesado ...

+0

¿Estás usando [django-ckeditor] (http://pypi.python.org/pypi/django-ckeditor) u otro widget? Si lo está escribiendo usted mismo, es correcto, no puede agregar algo a POST porque el cuerpo publicado es el archivo en sí. Entonces, sí, debes proporcionar el token en los parámetros de url. – ilvar

+0

incluso Django-CKEditor no utiliza protección CSRF para la carga de archivos (y esto es malo en mi humilde opinión): def @csrf_exempt subir (petición): """ carga un archivo y enviar su URL para CKEditor TODO:. Valida las cargas "" " – jmbarbier

Respuesta

5

Puede registrarse para el evento dialogDefinition, y reescribir completamente la pestaña de carga, por lo tanto:

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

Ésta es una no probada simplificación de mi versión del mundo real, pero con suerte muestra la idea.

Esto no configura el campo URL en el cuadro de diálogo de imagen, por lo que al hacer clic en Aceptar en el cuadro de diálogo aparecerá un mensaje de error. Usted tendrá que establecer que en una subida exitosa, por lo tanto:

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

Guau, respuesta fresca a la vieja pregunta :-) ¡Gracias! ... tu camino es mucho más limpio que mi piratería en el código ckeditor. Trataré de hacerlo la próxima vez que tenga que usar ckeditor. – jmbarbier

+0

Recibo: "TypeError no detectado: no se puede leer la propiedad 'getContentElement' de nulo" ¿Qué me falta? – Mladen

1

Parece que no hay manera de añadir datos a los datos CKEditor de carga sin edición código fuente ckeditor. El código fuente que se modificará es plugins/dialogui/plugin.js, alrededor de las líneas 1440 en ckeditor 3.6.2, donde ckeditor crea el formulario utilizado por el iframe de carga.

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

Y ahora podemos utilizar de forma segura cargar en CKEditor con Django

2

Los datos adicionales enviados al servidor se pasa por la petición GET. Yo estaba tratando de añadir datos adicionales y, finalmente, lograr esto añadiendo a unos parámetros de URL de la forma que se utiliza para enviar datos

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

he experimentado un problema similar cuando la integración de carga de imágenes a través de CKEditor para Elgg. La solución menos intrusiva que se me ocurrió fue que se une al evento de clic del botón de enviar y modificar la forma directamente de que:

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

La pregunta es demasiado viejo, pero ...

versión 4.5 se puede agregar gancho en cualquier solicitud

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

No funciona con la carga predeterminada de FileBrowser: http://stackoverflow.com/questions/34851158/ckeditor-4-5-fileuploadrequest-event-not-firing –

0

Siempre que está enviando un token de RFCE en la dirección URL a través de HTTPS debería estar bien para hacer eso (de una pinta de vista de seguridad), y también mucho más fácil de tratar.

Eso supone que django puede leer esa variable o usted puede fácilmente modificar django. Estas respuestas que intentan alterar CKeditor parecen demasiado trabajo.

Siempre que el navegador de los usuarios envíe su CSFR_token de forma segura al servidor, no importa si es a través de POST o GET. La preocupación de seguridad en juego es un hombre en el ataque medio, es decir, no desea que los usuarios transmitan CSFR_token en texto sin formato.

Estrictamente hablando, este tipo de datos deben enviarse como POST de acuerdo con la especificación HTTP, pero parece una situación en la que 'mal usar' el protocolo GET podría ser aceptable ya que no tiene control del código CKEditor particularmente manera elegante.

También podría quedar atrapado si CKEditor cambia cosas en una actualización, pasando el token a través de la URL siempre funcionará.

Cuestiones relacionadas