如何使用Express安全地上传Node中的文件?

在节点中有很多关于file upload的文章,教程和问题,但大部分是针对初学者的,并没有一个完全解释了如何保证file upload的生产。 我很努力地find一个完整的答案,但是没有成功。

以下是我的发现的解释。

  1. 限制上传的文件大小:

    app.use(express.limit('4mb')); 
  2. 限制file upload到只有某些路线:我不能得到这个实际工作,但这里是我曾经试过:

    更换:

     app.use(express.bodyParser()); 

     app.use(express.json()); app.use(express.urlencoded()); 

    并将多部分中间件添加到每个上载路由:

     app.post('/upload', express.multipart(), uploadController.uploadPhoto); 

    这部分不起作用,但如果我离开express.bodyParser() ,上传工作正常。 那么我做错了什么?

  3. 在保存上传到磁盘之前检查上传的文件types:

    我无法弄清楚这一部分,但有一个build议是编写一个自定义中间件,使用强大的parsingfile upload,并试图调整文件的大小,然后保存(假设它是一个图像)使用图像魔术库。 build议这样做会使图像安全并确保它实际上是一个图像(因为如果图像不是图像,该过程将失败)。

    这只会影响图像,所以它不是一个完整的解决scheme。

    我怎样才能实现呢? 任何示例代码?

还有什么,我失踪上传是安全的?

方法2实际上起作用。 我遇到的问题是

 app.use(passport.session()); 

正在阻止它的工作。 因此,如果您使用passport.js进行身份validation,则可能是此问题。 如果您使用这种方法,请确保在实际路线上添加安全性。


我结束了使用这个插件

https://github.com/tih-ra/alleup

它可以很好的与图片上传,并自动调整文件的大小,并将其上传到亚马逊S3。 使用这个插件将使用方法3内联,但文件首先上传到tmp文件夹,然后删除。

我正在使用多方上传(和stream媒体)的文件。

var form = new multiparty.Form();

到1:

 form.on('progress', function (bytesReceived) { if (262144000 < bytesReceived) { abortConnection('filesizeexeeded'); } }); 

实现你自己的中止连接function; 例如:

 function abortConnection(reason) { res.writeHead(413, { 'Connection': 'close' }); return res.end(reason); } 

警告:浏览器很可能会重试上传(最多4次)。 我正在使用websocket连接来取消客户端的上传。

到2 :(使用多方)

到3:我创build了一个要点 ,显示如何使用mmmagic在飞行中检查MIMEtypes。

如果您使用护照与多方相结合,您可能会发现这是有用的:

https://github.com/jaredhanson/passport/pull/106#issuecomment-14188999