【问题标题】:CSRF issues when integrating TinyMCE image upload with CakePHP 3.8将 TinyMCE 图像上传与 CakePHP 3.8 集成时的 CSRF 问题
【发布时间】:2019-10-29 13:08:24
【问题描述】:

我正在使用 CakePHP 3.8 为网站创建 CMS。我需要一个带有图像上传功能的简单所见即所得编辑器。我以前使用过 CKEditor,但在上传图片时遇到问题,所以我想试试 TinyMCE。

所以,我下载了 TinyMCE 5(带有所有标准插件),将其链接到我页面的 head 部分,并创建了一个带有 TinyMCE 文本区域的表单,如下所示:

<fieldset>
    <legend>New Page</legend>
    <?php
        echo $this->Flash->render();
        echo $this->Form->create($newpage);
        echo $this->Form->control('title');
        echo $this->Form->control('content', 
                      array('label' => 'Page Content',
                            'type' => 'textarea', 
                            'id' => 'editor_area'));
        echo $this->Form->button('Save');
        echo $this->Form->end();
    ?>
</fieldset>

<script>
    tinymce.init({
        selector:'#editor_area',
        height: 500,
        menubar: false,
        images_upload_url: '<?php echo IMG_UPLOAD_URL ?>',
        toolbar: [
            'undo redo | cut copy paste | styleselect | bold italic underline removeformat | alignleft aligncenter alignright | charmap | bullist numlist | link image'
        ],
        plugins: ['advlist lists link autolink image charmap imagetools code']
    });
</script>

这工作正常,文本区域出现在编辑器等处。images_upload_url 中的上传 url 指向以下UploadsController.php(为简洁起见,我省略了详细信息;如果需要,可以添加它们):

<?php
namespace App\Controller\Admin;

use App\Controller\AppController;

class UploadsController extends AppController
{

    public function uploadImage() {

        $result = array();
        $result['success'] = 'success';

        // Process file upload

        return $this->response->withType('application/json')
                    ->withStringBody(json_encode($result));

    }

}

当我上传图片时,我在控制台中收到以下错误:

Failed to load resource: the server responded with a status of 403 (Forbidden) 

CakePHP 的输出显示错误:

Error: CSRF token mismatch.

调试器显示 POST 包含以下内容:

Cookie: CAKEPHP=dvsktjv7vp8la5nv7dv19634d1; csrfToken=53e5718e13a1e963d51f9c93c48471a478b35c02b565d6f0699cd2a335775c2b17986cfc2cc587ff7343a6573e3eb2e498a9cb962397599c023417d1dfa9506c; ckCsrfToken=7l2PEC0g06819qQcLwdX5ul7E7jNRa3r61jENt2x

我不知道从这里去哪里。

(或者,如果有更直接的方法来包含一个免费/便宜的所见即所得编辑器和一个像样的图像/文件上传器,我愿意接受建议!这是一个学校的网站,所以预算非常小,不能是每月费用。)

【问题讨论】:

    标签: cakephp tinymce cakephp-3.0 csrf


    【解决方案1】:

    cookie 数据只是 CSRF 保护机制的一部分,客户端也需要在请求数据或X-CSRF-Token header 中发送 CSRF 令牌。

    我对 TinyMCE 图像上传不太熟悉,但查看文档,您可能需要一个自定义上传处理程序,您可以在其中添加其他数据,即 CSRF 令牌。

    使用the example from the TinyMCE docs,处理程序可能看起来像这样,其中 CSRF 令牌附加到表单数据:

    images_upload_handler: function (blobInfo, success, failure) {
        var xhr, formData;
    
        xhr = new XMLHttpRequest();
        xhr.withCredentials = false;
        xhr.open('POST', <?= json_encode(IMG_UPLOAD_URL) ?>);
    
        xhr.onload = function() {
            var json;
    
            if (xhr.status != 200) {
                failure('HTTP Error: ' + xhr.status);
                return;
            }
    
            json = JSON.parse(xhr.responseText);
    
            if (!json || typeof json.location != 'string') {
                failure('Invalid JSON: ' + xhr.responseText);
                return;
            }
    
            success(json.location);
        };
    
        formData = new FormData();
        formData.append('file', blobInfo.blob(), blobInfo.filename());
        // append CSRF token in the form data
        formData.append('_csrfToken', <?= json_encode($this->request->getParam('_csrfToken')) ?>);
    
        xhr.send(formData);
    }
    

    此外,根据文档,响应 JSON 必须包含一个名为 location 的属性,其中包含上传文件的网络路径,这可能在您遗漏的代码中,以防万一。

    另见

    【讨论】:

    • 我发现您的解决方案非常有用,但您是否介意添加一个关于如何在 TinyMCE 上删除图像时删除图像的简短简介,这样看起来图像会永远保留在那里。
    • @SarojShrestha 我不知道你到底指的是什么,但这听起来像是无关的,应该在一个单独的问题中解释。
    猜你喜欢
    • 2011-12-07
    • 1970-01-01
    • 2021-06-01
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    相关资源
    最近更新 更多