node.js - 有时我会收到带有多部分表单的无效 csrf token

标签 node.js express upload csrf formidable

我使用带有csurf和强大的expressjs 4,有时当我使用多部分表单上传时:

Error: invalid csrf token at createToken (/Users/mecha/projects/sherka/maktabi/node_modules/csurf/index.js:94:19) at Layer.handle (/Users/mecha/projects/sherka/maktabi/node_modules/csurf/index.js:59:24) at trim_prefix (/Users/mecha/projects/sherka/maktabi/node_modules/express/lib/router/index.js:240:15) at /Users/mecha/projects/sherka/maktabi/node_modules/express/lib/router/index.js:208:9 at Function.proto.process_params (/Users/mecha/projects/sherka/maktabi/node_modules/express/lib/router/index.js:269:12) at next (/Users/mecha/projects/sherka/maktabi/node_modules/express/lib/router/index.js:199:19) at /Users/mecha/projects/sherka/maktabi/node_modules/express-session/index.js:226:9 at Object._onImmediate (/Users/mecha/projects/sherka/maktabi/node_modules/express-session/session/memory.js:58:9) at processImmediate [as _immediateCallback] (timers.js:330:15)

但有时它工作正常,没有任何错误,知道我做错了什么吗?

这是我的代码

app.use(function(req, res, next){
    res.locals.session = req.session;
    res.locals.messages = req.flash('success');
    res.locals.errors = req.flash('error');
    res.locals.csrftoken = req.csrfToken();
    next();
});

这是一个 html 表单

<form id="new_desk_form" class="form" method="post" action="/space/{{ space.id}}/add/desk?_csrf={{ csrftoken }}" enctype="multipart/form-data">

这是路由处理程序

app.post('/space/:id/add/desk', helpers.ensureAuth, function(req, res){
    var id = req.params.id;
    var form = new formidable.IncomingForm();
    form.uploadDir = __dirname+'/../public/uploads/spaces/'+id;
    form.keepExtensions = true;
    form.encoding = 'utf-8';
    form.parse(req, function(err, fields, files){
        if(err){
            console.log(err);
            res.render('505.html')
        }
        var name = files.photo1.path.split('/');
        name = name[name.length-1];
        var pathToStore = "/uploads/spaces/"+id+'/'+name;
        var workspace = {};
        workspace.title = req.body.title;
        workspace.type = 'desk';
        workspace.photos = [];
        workspace.photos.push(pathToStore);
        workspace.currency = req.body.currency;
        workspace.quantity = req.body.quantity;
        workspace.prices = {};
        if(req.body.hourly){
            workspace.prices.hourly = req.body.hourly;
        }
        if(req.body.daily){
            workspace.prices.daily = req.body.daily;
        }
        if(req.body.monthly){
            workspace.prices.monthly = req.body.monthly;
        }
        Space.findOne({_id: id}, {}, function(err, space){
            if(err){
                console.log(err);
                    res.render('505.html');
            }
            space.workspaces.push(workspace);
            space.save(function(){
                res.redirect('/edit/'+req.id);
            })
        });
    });
});

最佳答案

您遇到的问题是编码问题。当 CSRF token 验证失败时,很可能是由于 CSRF token 具有正斜杠 /或其他需要在 URL 查询字符串中正确编码的字符。这种编码与句柄对带有两个大括号的变量进行的转义不同。

我建议使用隐藏输入,然后浏览器应在提交表单时对其进行正确编码:

<input type="hidden" name="_csrf" value="{{ csrftoken }}">

或者,您也可以确保 csrftoken贯穿encodeURIComponent()在包含在action之前表单的属性。您可能想使用 Handlebars 助手来完成此操作,我相信您将需要第三方助手来完成此操作,这是一个选项:handlebars-helpers

关于node.js - 有时我会收到带有多部分表单的无效 csrf token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23985802/

相关文章:

mysql - 您可以将 Okta 与 mysql 一起使用吗?

php - 如何使用 php 将图像大小调整为 75%?

mysql - yii 1.1 中的外键和上传照片

javascript - 使用 node.js 编写用于图像上传的过滤器列表的设计模式

javascript - 返回 [object Object] 的闪存消息(Node Express Passport)

php - Linux cURL 与 PHP cURL - POST 请求

node.js - 如何从服务器端(使用 NodeJS sdk)将设备注册到 Azure 通知中心?

javascript - 使用nodejs发送和接收数据而不将其显示在我的页面上?

javascript - CreateReadStream 在 block 中创建额外的换行符?

node.js - 如何在 socket.io 连接中获取持久的快速 session ID?