CSRF和Multer - 无效的CSRF令牌错误

3
我在为我的多部分表单添加CSRF令牌以保持提交安全时遇到了问题。我已经在我的app.js文件中将CSRF生成设置为全局的req对象,并且除了multipart之外,没有其他类型的Web表单问题。我已经阅读过这是multer的常见问题,与CSRF的放置方式有关,要么与multer设置一起使用,要么将其附加为提交查询。出于安全原因,我不想采用附加查询的方法,而希望看到如何修复我的设置,使其像我的其他表单一样运行。

错误信息:

ForbiddenError: invalid csrf token
    at csrf (/Users/user/Desktop/Projects/node/test-app/node_modules/csurf/index.js:112:19)

app.js:

var csrf = require('csurf');
....

//Set CSRF for Form Tokens
app.use(csrf());
app.use(function(req, res, next){
    res.locals._csrf = req.csrfToken();
    next();
});

路由:

var upload = multer({
    storage: multerS3({
        s3: s3,
        bucket: options.Bucket,
        contentType: multerS3.AUTO_CONTENT_TYPE,
        acl: options.ACL,
        key: function(req, file, cb){
            var fileNameFormatted = file.originalname.replace(/\s+/g, '-').toLowerCase();
            cb(null, req.user.organizationId + '/' + uploadDate + '/' + fileNameFormatted);
        }
    }),
    fileFilter: function(req, file, cb){
        if(!file.originalname.match(/\.(jpg|jpeg|png|gif|csv|xls|xlsb|xlsm|xlsx)$/)){
            return cb('One of your selected files is not supported', false);
        }
        cb(null, true);
    }
}).array('fileUpload', 5);


appRoutes.route('/blog/create')

.get(function(req, res){
    res.render('pages/app/blog-create.hbs',{
        errorMessage: req.flash('error'),
        csrfToken: req.csrfToken()
    });
})

.post(function(req, res){

upload(req, res, function(err){
            if(err){
                req.flash('error', err);
                res.redirect(req.get('referer'));
                return;
            }

 models.Blog.create({
                date: req.body.date,
                title: req.body.title,
                content: req.body.content,
                userId: req.user.userId     
            }).then(function(){
                req.flash('info', 'Blog was successfully created.');
                res.redirect('/app');
            });
})
});

视图:

<form action="/app/blog/create" method="post" enctype="multipart/form-data" id="blogSubmission">
                <input type="hidden" name="_csrf" value="{{csrfToken}}">

....
</form>
2个回答

1

只需要在 csurf 之前添加 Multer -

app.use(multer().single('image-field-name'));
app.use(csurf());

确保在POST期间传递_csrf值 -

<input type="hidden" name="_csrf" value="<%= csrfToken %>">

如果上述解决方案不起作用,那么只需在POST操作中添加"_csrf"值即可。
<form action="/admin/?_csrf=<%=csrfToken%>" method="POST" enctype="multipart/form-data">
</form>

-1

嗨 :) 这有点晚了,但首先我可能不是一个好的英语说话者,所以如果你看到任何语法或拼写错误,请使用

{try(){understand()}catch(e){/*do nothing :)*/}}

方法 :) )

我上个月遇到了你的问题,情况很糟糕,我找不到一个好的答案。

但是现在你来了 :)))(老实说,我不太擅长阅读别人的代码,所以请看一下我的答案并想办法编辑你的代码)

说实话,如果您想使用常规的发布表单方法,那么没有一个好的答案(有一种方法建议您先获取和保存文件,然后检查它的csrf,但我真的不太喜欢)。但是,如果您愿意做一些前端JavaScript工作,那么今天就是您的幸运日:

整个想法是为您的表单设置一个标题,然后发送它(全部使用AJAXJQuery):

以下是应该如何进行的简单示例:

$.ajax({
    cache: false,
    type: 'POST',
    url: 'the URL you want to post to',
    contentType: "what ever you want",
    headers: {"X-CSRF-TOKEN": csrfToken},
    data: your data,
    success: function (res) {
        some code after you get a response from server
        console.log(res)
    }
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接