我正在使用带有csurf和强大的expressjs 4,有时当我使用多部分表单上传时:
错误:csrf令牌无效 at createToken(/Users/mecha/projects/sherka/maktabi/node_modules/csurf/index.js:94:19) 在Layer.handle(/Users/mecha/projects/sherka/maktabi/node_modules/csurf/index.js:59:24) 在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 在Function.proto.process_params(/Users/mecha/projects/sherka/maktabi/node_modules/express/lib/router/index.js:269:12) 在下一个(/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);
})
});
});
});
答案 0 :(得分:4)
您遇到的问题是编码问题。当CSRF令牌无法验证时,很可能是由于CSRF令牌具有正斜杠/
或需要在URL查询字符串中正确编码的其他字符。这种编码不同于手柄对具有两个花括号的变量的转义。
我建议使用隐藏的输入,然后浏览器应该在提交表单时正确编码:
<input type="hidden" name="_csrf" value="{{ csrftoken }}">
或者,您还可以确保csrftoken
在action
中运行,然后才会包含在表单的{{1}}属性中。你可能想用一个把手帮手来做这个,我相信你需要一个第三方助手来做,这里有一个选项:encodeURIComponent()