8

私はdjangockeditorを使用して、TextEditsにwysiwygのテイストを提供しています。(ファイルブラウザ/画像ダイアログで)CKEditorファイルアップロード機能を使用したいのですが、画像をアップロードするためにCKEditorが作成したPOSTにはファイルデータしか含まれていません。

これはCSRFチェックの問題です。CKEditorのドキュメントで見つからず、ファイルアップロード用のPOSTデータを変更して、POSTデータにdjangoのcsrf_tokenを追加する場所を入手できませんでした。

回避策として、filebrowserUploadUrlパラメーターを変更してアップロードURLにcsrfデータを含め、アップロードビューに@csrf_exemptを使用し、request.GETパラメーターをチェックしてcsrfをチェックできます。しかし、このソリューションは安全ですか?

とにかく、誰かがcsrfトークンをCKEditorファイルアップロードPOSTデータに直接含める方法を知っているなら、私は強く興味があります...

4

6 に答える 6

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フィールドを設定しないため、ダイアログで[OK]をクリックするとエラーメッセージが表示されます。アップロードが成功したら、次のように設定する必要があります。

CKEDITOR.dialog.getCurrent().getContentElement('info', 'txtUrl').setValue(theURL);
于 2013-11-06T15:36:34.610 に答える
3

サーバーに送信される追加データは、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               
              */ 

     }
   });
于 2014-07-02T22:21:34.880 に答える
2

Elgg用のCKEditorを介して画像のアップロードを統合するときに、同様の問題が発生しました。私が思いついた最も邪魔にならない解決策は、送信ボタンの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;
            };
        }
    }
});
于 2014-10-17T20:03:01.110 に答える
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で安全にアップロードを使用することができます

于 2012-05-04T21:31:02.577 に答える
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;
} );
于 2015-12-10T23:51:33.180 に答える
0

HTTPSを介してURLでCSFRトークンを送信している場合は、(セキュリティの観点から)それを実行しても問題はなく、処理もはるかに簡単です。

これは、djangoがその変数を読み取ることができるか、djangoを簡単に変更できることを前提としています。CKeditorを変更しようとするこれらの回答は、少しやりすぎのようです。

CSFR_tokenがユーザーのブラウザによって安全な方法でサーバーに送信されている限り、それがPOSTまたはGETのどちらを経由しているかは関係ありません。セキュリティ上の懸念は中間者攻撃です。つまり、ユーザーのCSFR_tokenがプレーンテキストでブロードキャストされることは望ましくありません。

厳密に言えば、この種のデータはHTTP仕様に従ってPOSTとして送信する必要がありますが、これは、特に洗練された方法でCKEditorコードを制御できないため、GETプロトコルの「誤用」が許容される状況のようです。

また、CKEditorがアップグレードで変更を加えた場合に巻き込まれる可能性があり、URLを介してトークンを渡すことは常に機能します。

于 2017-10-13T10:28:05.803 に答える