2012-07-12 62 views
4

我正在使用express.js和节点处理文件上载,并且具有基本功能。我需要的是实施一些安全措施 - 即将上传限制为某些格式(PNG,JPEG)。有没有简单的方法只允许某些格式?它会进入身体解析器吗?使用express.js和节点上传文件,限制扩展

app.use(express.bodyParser({ 
    uploadDir: __dirname + '/public/uploads', 
    keepExtensions: true })); 

app.use(express.limit('4mb')); 

是否还有其他安全措施需要考虑?从图像中擦除EXIF数据通常是一个好主意?

感谢,

回答

5

根据documentation for connect's bodyParser,任何选项也会传递给formidable,它会进行实际的表单解析。

formidable docs,你可以通过你自己的onPart处理程序:

incomingForm.onPart(部分)

,如果你有兴趣在直接访问多数据流,您可以覆盖此方法。这样做会禁用任何可能发生的'字段'/'文件'事件处理,使您完全负责处理处理。

incomingForm.onPart = function(part) { 
    part.addListener('data', function() { 
    // ... 
    }); 
} 

如果你想使用强大的,只为你处理某些部分,你可以这样做:

incomingForm.onPart = function(part) { 
    if (!part.filename) { 
    // let formidable handle all non-file parts 
    incomingForm.handlePart(part); 
    } 
} 

总之,你应该能够做这样的事情:

function onPart(part) { 
    if(!part.filename || part.filename.match(/\.(jpg|jpeg|png)$/i)) { 
     this.handlePart(part); 
    } 
} 

app.use(express.bodyParser({onPart: onPart}); 

警告:我还没有测试过这些。

+0

这是伟大的,莱纳斯,似乎工作。两个问题:(1)比较内容类型和文件名是否更好? (2)我应该如何处理不支持的格式?其他{res.send(403)}? – bento 2012-07-12 19:40:59

+0

我不确定'part'中有什么可用的,但是如果你有内容类型,我会和它进行比较。关于你如何处理'else'情况,我不确定你有什么选择。你真的没有在那里访问'res',我不知道这是多么强大的句柄。在我上面的例子中,我认为它会忽略该文件。 – 2012-07-12 20:06:40

+0

哦,你应该也可以''this.handlePart(part)'那些没有文件名的情况下 - 我已经更新了答案。 – 2012-07-12 20:08:20

2

我发现了一个潜在的解决方案:

在你的中间件,

if (req.files[key].type != 'image/png' && req.files[key].type != 'image/jpeg'){ 
     res.send(403); 
    } else { 
     next(); 
    } 

更新:这不会真正停止从上传文件,虽然。