【问题标题】:Upload file and validate csrf token with express上传文件并使用 express 验证 csrf 令牌
【发布时间】:2019-11-18 07:08:42
【问题描述】:

我正在与mongodbnodejsexpress 合作。 我有一个发送post 请求以使用multer-gridfs 上传文件的表单。 在表单中,我只有input 用于上传文件,hidden input 用于csrf。请求通过ajax 发送。问题是我发送 ajax 请求时对csrf token 的验证

上传图片的表格

<form enctype='multipart/form-data' id="upload-file-form" enctype="multipart/form-data" >
    <input type="file" name="file" id="file">
    <input type="hidden" name="_csrf" value="<%= csrfToken %>">
</form>

AJAX

function upload_image(){
    console.log('upload image')
    var fd = new FormData($("#upload-file-form").get(0));
    console.log(fd);
    var token = $('input[name="_csrf"]').val();

    $.ajax({
        url: '/posts/upload' ,
        data: {fd: fd, _csrf: token },
        dataType: 'json',
        type: 'POST',
        processData: false,
        contentType: false,
        success: function (response) {
            console.log(response);
        },
        error: function (xhr, status, error) {
            console.log('Error: ' + error.message);
        }
    })
}

错误

ForbiddenError: invalid csrf token
    at csrf (/home/pero/motoWebApp/node_modules/csurf/index.js:112:19)
    at Layer.handle [as handle_request] (/home/pero/motoWebApp/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/pero/motoWebApp/node_modules/express/lib/router/index.js:317:13)
    at /home/pero/motoWebApp/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/pero/motoWebApp/node_modules/express/lib/router/index.js:335:12)
    at next (/home/pero/motoWebApp/node_modules/express/lib/router/index.js:275:10)
    at Immediate.<anonymous> (/home/pero/motoWebApp/node_modules/express-session/index.js:495:7)
    at runCallback (timers.js:706:11)
    at tryOnImmediate (timers.js:676:5)
    at processImmediate (timers.js:658:5)

监听 AJAX 请求的路由

const GridFsStorage             = require('multer-gridfs-storage'),
      multer                    = require('multer');

const mongoURI = "mongodb://localhost:27017/app";

// Create storage engine
const storage = new GridFsStorage({
  url: mongoURI,
  file: (req, file) => {
    return new Promise((resolve, reject) => {
      crypto.randomBytes(16, (err, buf) => {
        if (err) {
          return reject(err);
        }
        const filename = buf.toString('hex') + path.extname(file.originalname);
        const fileInfo = {
          filename: filename,
          bucketName: 'uploaded_images' //collection name
        };
        resolve(fileInfo);
      });
    });
  }
});
const upload = multer({
    storage: storage,
});


router.post('/posts/upload', upload.single('file'), function(req, res){ 
    res.send(JSON.stringify(req.file.filename))
});

我看到,为了通过ajax 验证csrf toke,您必须在ajax 请求的data 属性中指定它,我这样做了。我认为问题是由processDatacontentType 属性引起的 设置为false

如果我删除这些属性,代码不会引发invalid csrf token 错误,但在浏览器中会打印TypeError: 'append' called on an object that does not implement interface FormData.

【问题讨论】:

  • 您是否使用了合适的会话中间件/cookie-parser?
  • 是的,我找到了解决办法

标签: node.js ajax express multer


【解决方案1】:

我发现要上传图像并验证csrf 令牌,而不是在data 调用的data 属性内传递csrf 令牌,您应该将其设置在@ 的header 属性内987654326@电话

你必须这样做

var form = $("#upload-file-form");
var fd = new FormData(form.get(0));
var token = $("#upload-file-form input[name='_csrf']").val();
$.ajax({
        url: '/posts/upload' ,
        headers: {"X-CSRF-TOKEN": <your token>},
        data: {your datas},
        dataType: 'json',
        type: 'POST',
        processData: false,
        contentType: false
   });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-08
    • 2014-07-12
    • 2017-12-14
    • 2018-05-10
    • 2019-03-22
    • 2015-01-31
    • 2018-02-01
    • 1970-01-01
    相关资源
    最近更新 更多