Nodejs中怎么判断一个图片是否伪图片

Nodejs中怎么判断一个图片是否伪图片

网站有让用户上传图片功能,怎么判断上传上来的图片是真正的图片而不是其他文件只修改了个扩展名的伪图片呢

6 回复

网站有让用户上传图片功能,怎么判断上传上来的图片是真正的图片而不是其他文件只修改了个扩展名的伪图片呢


Magic number 是指檔案前 16-bit 字元,用來判斷該檔案的類型

用 Node.js 來寫的話,應該是讀取檔案 Buffer 然後判斷 Magic number,例如:

var fs = require('fs')

fs.readFile(’./path/to/image.jpg’, function(err, buf) {

var JPG_MAGIC_NUMBER = ‘ffd8’

if (buf.toString(‘hex’, 0, 2) === JPG_MAGIC_NUMBER) { return console.log(‘this file is JPG’) }

console.log(‘this file is not JPG’)

})

[@chinghanho](/user/chinghanho) 这样是个办法,但是客户很聪明的在文件最前面加了这个特征,然后才是他的内容,

说个想法,用phantomjs上用固定尺寸显示上载的图片,非图片会显示出错,页面上是默认的broken image图像。

在Node.js中处理用户上传的图片时,确保这些图片确实是有效的图像文件非常重要。有时候,用户可能会尝试通过修改文件扩展名来上传非图片文件,这可能导致安全问题或应用崩溃。为了防止这种情况,我们可以使用一些库来验证文件内容是否符合某种图像格式(如JPEG、PNG等)。

使用sharp库进行图片验证

sharp是一个高性能的Node.js图像处理库,它可以用来检查图片的有效性。以下是如何使用sharp来验证图片是否为有效图像的示例代码:

  1. 首先,安装sharp库:

    npm install sharp
    
  2. 然后,在你的项目中使用它来验证图片:

    const fs = require('fs');
    const sharp = require('sharp');
    
    function isValidImage(filePath) {
        return new Promise((resolve, reject) => {
            sharp(fs.createReadStream(filePath))
                .metadata()
                .then(meta => {
                    if (meta.format) {
                        resolve(true); // 图片格式正确
                    } else {
                        resolve(false); // 不是有效的图片
                    }
                })
                .catch(err => {
                    console.error('图片验证失败:', err);
                    resolve(false); // 验证失败
                });
        });
    }
    
    // 使用函数
    const filePath = 'path/to/your/image.jpg';
    isValidImage(filePath)
        .then(isValid => {
            if (isValid) {
                console.log('图片有效');
            } else {
                console.log('图片无效');
            }
        });
    

解释

  • sharp库提供了强大的图像处理能力,包括读取和验证图像文件。
  • sharp.metadata()方法会尝试从给定的图像文件中读取元数据。如果文件不是有效的图像文件,该方法将抛出错误。
  • 我们通过捕获可能的错误并返回布尔值来确定文件是否为有效的图像文件。

这种方法可以有效地防止用户通过修改文件扩展名来上传非图片文件,从而增强应用程序的安全性和稳定性。

为了判断上传的图片是否为真正的图片(即其内容确实是图片格式),可以使用 Node.js 中的一些库来检查文件头(文件开头的几个字节),这些字节通常被称为魔数(magic number)。魔数对于不同类型的文件都是唯一的,可以通过检查这些魔数来判断文件类型。

这里提供一个简单的示例代码,展示如何使用 file-type 库来检查文件是否为真实的图片。首先,你需要安装 file-type 库:

npm install file-type

然后你可以使用以下代码进行判断:

const fs = require('fs');
const fileType = require('file-type');

async function checkIfImageIsValid(filePath) {
    try {
        const buffer = fs.readFileSync(filePath);
        const detectedFileType = await fileType.fromBuffer(buffer);

        if (detectedFileType && detectedFileType.mime.startsWith('image/')) {
            console.log(`The file at ${filePath} is a valid image of type ${detectedFileType.ext}.`);
            return true;
        } else {
            console.log(`The file at ${filePath} is not a valid image.`);
            return false;
        }
    } catch (error) {
        console.error(`Error checking file: ${error.message}`);
        return false;
    }
}

// 使用示例
checkIfImageIsValid('/path/to/your/image.jpg').then(isValid => {
    // 这里可以根据 isValid 的结果决定下一步的操作
});

解释:

  • fs.readFileSync 读取文件并返回其内容作为 Buffer。
  • fileType.fromBuffer(buffer) 检查 Buffer 中的内容,并返回文件的类型信息。
  • 如果文件的 MIME 类型以 image/ 开头,则认为这是一个有效的图片文件。

这种方法可以有效防止用户通过更改扩展名来绕过文件验证。请注意,在实际应用中,你可能还需要结合其他安全措施,例如限制上传文件的大小、类型等,以增强安全性。

回到顶部