如何使用Multer中间件验证文件扩展名

时间:2020-02-26 07:14:04

标签: node.js multer file-type

我使用Multer上传文件或图像。问题是无法验证真实文件扩展名。

示例:如果有人将OnApplicationQuit重命名为filename.exe,则仍然可以上传。

您能建议我解决该问题的解决方案吗?谢谢

我曾经这样使用,但需要验证文件的真实扩展名

filename.png

4 个答案:

答案 0 :(得分:4)

您应该同时检查扩展名和上载参数的MIME类型。这是示例代码。

const storage = multer.diskStorage({
    destination: './uploadedContent',
    filename: function(_req, file, cb){

      cb(null,file.fieldname + '-' + Date.now() + path.extname(file.originalname));
    } 
  });
var upload = multer({
    storage: storage,
    limits: {
        fields: 5,
        fieldNameSize: 50, // TODO: Check if this size is enough
        fieldSize: 20000, //TODO: Check if this size is enough
        // TODO: Change this line after compression
        fileSize: 15000000, // 150 KB for a 1080x1080 JPG 90
    },
    fileFilter: function(_req, file, cb){
        checkFileType(file, cb);
    }
}).single('postPicture');
function checkFileType(file, cb){
  // Allowed ext
  const filetypes = /jpeg|jpg|png|gif/;
  // Check ext
  const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
  // Check mime
  const mimetype = filetypes.test(file.mimetype);

  if(mimetype && extname){
    return cb(null,true);
  } else {
    cb('Error: Images Only!');
  }
}

别忘了检查您的文件权限。您不希望以某种方式执行上载的文件。

答案 1 :(得分:2)

基本上,您需要的是可以验证原始文件类型的扩展名的东西。

从博客复制

    var upload = multer({
  storage: storage,
  fileFilter: (req, file, cb) => {
    if (file.mimetype == "image/png" || file.mimetype == "image/jpg" || file.mimetype == "image/jpeg") {
      cb(null, true);
    } else {
      cb(null, false);
      return cb(new Error('Only .png, .jpg and .jpeg format allowed!'));
    }
  }
});

Blog Link

如果这不适用于您,请考虑使用单独的模块,该模块从缓冲区数据中验证文件类型。

答案 2 :(得分:1)

本文将为您提供帮助

www.positronx.io/multer-file-type-validation-tutorial-with-example

答案 3 :(得分:0)

有两个步骤:

  1. 根据 fileFilter 选项的 multer 提供的 mime 类型过滤
  2. 使用 file-type 从文件缓冲区/流中过滤真实的 MIME 类型。

定义白名单 MIME 类型:

const whitelist = [
  'image/png',
  'image/jpeg',
  'image/jpg',
  'image/webp'
]

第一步示例:

const upload = multer({
  storage: multer.diskStorage({
    destination: 'public/uploads/',
    filename: (req, file, cb) => {
      const name = slugify(file.originalname, { lower: true })
      cb(null, `${new Date().getTime()}-${name}`)
    },
  }),
  fileFilter: (req, file, cb) => {
    if (!whitelist.includes(file.mimetype)) {
      return cb(new Error('file is not allowed'))
    }

    cb(null, true)
  }
})

第二步示例:

const FileType = require('file-type')

// ....
// first step
// ....

/**
 * Second step
 */
app.use('store', upload.single('image'), async (req, res, next) => {
  const meta = await FileType.fromFile(req.file.path)

  if (!whitelist.includes(meta.mime)) {
    return next(new Error('file is not allowed'))
  }

  res.json({
    file: req.file,
    body: req.body,
  })
})

我尝试重命名 document.pdf -> document.png,它通过了第一次检查,但在第二次检查中被发现了。