Node.js 在启用csrf之前,Express4和强大的文件上传都可以正常工作
我正在阅读Ethan Brown的书“使用Node和Express进行Web开发”,一直进展顺利,直到我在照片上传中启用了csrf多部分/表单数据上传。我从Github下载了完整的书籍代码,这也做了同样的事情,直到启用csrf,然后它会出现以下错误: 错误:无效的csrf令牌 以下是我认为相关的代码位,/meadowlark.js从第100行开始Node.js 在启用csrf之前,Express4和强大的文件上传都可以正常工作,node.js,express,formidable,Node.js,Express,Formidable,我正在阅读Ethan Brown的书“使用Node和Express进行Web开发”,一直进展顺利,直到我在照片上传中启用了csrf多部分/表单数据上传。我从Github下载了完整的书籍代码,这也做了同样的事情,直到启用csrf,然后它会出现以下错误: 错误:无效的csrf令牌 以下是我认为相关的代码位,/meadowlark.js从第100行开始 app.use(require('cookie-parser')(credentials.cookieSecret)); app.use(requir
app.use(require('cookie-parser')(credentials.cookieSecret));
app.use(require('express-session')({ store: sessionStore,
secret: credentials.cookieSecret,
name: credentials.cookieName,
saveUninitialized: true,
resave: true }));
app.use(express.static(__dirname + '/public'));
app.use(require('body-parser')());
// cross-site request forgery protection
app.use(require('csurf')());
app.use(function(req, res, next){
res.locals._csrfToken = req.csrfToken();
next();
});
// database configuration
var mongoose = require('mongoose');
var options = {
server: {
socketOptions: { keepAlive: 1 }
}
};
然后在/handlers/contest.js中
var path = require('path'),
fs = require('fs'),
formidable = require('formidable');
// make sure data directory exists
var dataDir = path.normalize(path.join(__dirname, '..', 'data'));
var vacationPhotoDir = path.join(dataDir, 'vacation-photo');
fs.existsSync(dataDir) || fs.mkdirSync(dataDir);
fs.existsSync(vacationPhotoDir) || fs.mkdirSync(vacationPhotoDir);
exports.vacationPhoto = function(req, res){
var now = new Date();
res.render('contest/vacation-photo', { year: now.getFullYear(), month: now.getMonth() });
};
function saveContestEntry(contestName, email, year, month, photoPath){
// TODO...this will come later
}
exports.vacationPhotoProcessPost = function(req, res){
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files){
if(err) return res.redirect(303, '/error');
if(err) {
res.session.flash = {
type: 'danger',
intro: 'Oops!',
message: 'There was an error processing your submission. ' +
'Pelase try again.',
};
return res.redirect(303, '/contest/vacation-photo');
}
var photo = files.photo;
var dir = vacationPhotoDir + '/' + Date.now();
var path = dir + '/' + photo.name;
fs.mkdirSync(dir);
fs.renameSync(photo.path, dir + '/' + photo.name);
saveContestEntry('vacation-photo', fields.email,
req.params.year, req.params.month, path);
req.session.flash = {
type: 'success',
intro: 'Good luck!',
message: 'You have been entered into the contest.',
};
return res.redirect(303, '/contest/vacation-photo/entries');
});
};
exports.vacationPhotoEntries = function(req, res){
res.render('contest/vacation-photo/entries');
};
还有观景/比赛/度假照片.车把
<form class="form-horizontal" role="form"
enctype="multipart/form-data" method="POST"
action="/contest/vacation-photo/{{year}}/{{month}}">
<input type="hidden" name="_csrf" value="{{_csrfToken}}">
<div class="form-group">
<label for="fieldName" class="col-sm-2 control-label">Name</label>
<div class="col-sm-4">
<input type="text" class="form-control"
id="fieldName" name="name">
</div>
</div>
<div class="form-group">
<label for="fieldEmail" class="col-sm-2 control-label">Email</label>
<div class="col-sm-4">
<input type="email" class="form-control" required
id="fieldName" name="email">
</div>
</div>
<div class="form-group">
<label for="fieldPhoto" class="col-sm-2 control-label">Vacation photo</label>
<div class="col-sm-4">
<input type="file" class="form-control" required accept="image/*"
id="fieldPhoto" data-url="/upload" name="photo">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-4">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
名称
电子邮件
度假照
提交
使csrf工作的正确方法是什么
谢谢,关于假期照片获取请求,您应该发送如下csrf令牌
exports.vacationPhotoEntries = function(req, res){
res.render('contest/vacation-photo/entries', { _csrfToken: req.csrfToken()});
};
// error handler
app.use(function (err, req, res, next) {
if (err.code !== 'EBADCSRFTOKEN') return next(err)
// handle CSRF token errors here
res.status(403)
res.send('session has expired or form tampered with')
})
您还可以在默认错误处理程序中捕获csrf令牌错误,如下所示
exports.vacationPhotoEntries = function(req, res){
res.render('contest/vacation-photo/entries', { _csrfToken: req.csrfToken()});
};
// error handler
app.use(function (err, req, res, next) {
if (err.code !== 'EBADCSRFTOKEN') return next(err)
// handle CSRF token errors here
res.status(403)
res.send('session has expired or form tampered with')
})
有关更多信息,请检查。将csrf令牌作为查询字符串附加到操作Url。。 它起作用了
<form class="form-horizontal" role="form" enctype="multipart/form-data" method="POST"
action="/contest/vacation-photo/{{year}}/{{month}}?_csrf={{_csrfToken}}">
</form>
谢谢Hojin,我完全忘记了这个问题,因为我的应用程序是内部的,所以我只是将该路径移动到CSRF中间件之前,直到我可以回来修复它。你的解决方案有效。现在看来,这似乎很简单,我想当时我的脑袋不在正确的位置。我想知道你的回答,但我没有足够的声誉点数。