将 TinyMCE 图片上传与 CakePHP 3.8 集成时出现 CSRF 问题
CSRF issues when integrating TinyMCE image upload with CakePHP 3.8
我正在使用 CakePHP 3.8 为网站创建 CMS。我需要一个简单的所见即所得的图片上传编辑器。我以前使用过 CKEditor,但在上传图片时遇到问题,所以我想试试 TinyMCE。
因此,我下载了 TinyMCE 5(带有所有标准插件),将其链接到我页面的头部,并创建了一个带有 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
我不知道从这里到哪里去。
(或者,如果有更直接的方法来包含一个 free/inexpensive 所见即所得的编辑器和一个体面的 image/file 上传器,我愿意接受建议!这是一个学校网站,所以预算是非常小,不可能是每月费用。)
cookie数据只是CSRF保护机制的一部分,客户端需要在请求数据或X-CSRF-Token
header中发送CSRF token。
我不太熟悉 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
的 属性,其中包含上传文件的 Web 路径,该路径可能在您的代码中已经遗漏了,提一下以防万一。
另见
我正在使用 CakePHP 3.8 为网站创建 CMS。我需要一个简单的所见即所得的图片上传编辑器。我以前使用过 CKEditor,但在上传图片时遇到问题,所以我想试试 TinyMCE。
因此,我下载了 TinyMCE 5(带有所有标准插件),将其链接到我页面的头部,并创建了一个带有 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
我不知道从这里到哪里去。
(或者,如果有更直接的方法来包含一个 free/inexpensive 所见即所得的编辑器和一个体面的 image/file 上传器,我愿意接受建议!这是一个学校网站,所以预算是非常小,不可能是每月费用。)
cookie数据只是CSRF保护机制的一部分,客户端需要在请求数据或X-CSRF-Token
header中发送CSRF token。
我不太熟悉 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
的 属性,其中包含上传文件的 Web 路径,该路径可能在您的代码中已经遗漏了,提一下以防万一。
另见