如何停止nodejs上的图像热链接?

zwghvu4y  于 2023-02-15  发布在  Node.js
关注(0)|答案(4)|浏览(82)

我如何防止人们使用nodejs和express在应用程序上热链接图片?我在自己的服务器上托管。我需要在app.js文件中内置一些东西吗?谢谢。

vngu2lb8

vngu2lb81#

你需要编写一个中间件,只接受来自你的网站的某些有效的引用。一定要接受现代搜索引擎,社交媒体网站,也不要接受引用。

zsohkypk

zsohkypk2#

如果你使用nginx和node,这里有一个solution
基本上,它检查引用者,如果未被授权,则返回403。
您还可以使用相同的逻辑为express编写中间件。

0ve6wy6x

0ve6wy6x3#

创建一个中间件来检查HTTP请求头中的Referer,域包括流行的搜索引擎、媒体和网站。
假设您使用的是express 4.x,将其添加到app.js文件中。

app.use('/', (req , res , next) => {
    const referrer = req.get('Referrer');
    if (referrer == null) {
      next(); // referrer is an optional http header, it may not exist
    }
    if (["https://www.facebook.com", "https://www.google.com"].includes(referrer)) {  // compare referrer with your whitelist
      res.status(403).send("You are not allowed to view this photo!"); // block the request
    }
    next();
});
app.get('/',(req,res)=>{
  res.sendFile(`PATH_OF_YOUR_IMAGE`);
});

了解有关Referer HTTP标头的详细信息
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer

suzh9iv8

suzh9iv84#

使用referrer的问题是,大多数热链接不使用此标头,浏览器也不发送标签中的图像或src="”属性...如果您的网站使用cookie,并且cookie被您网站的用户接受,您可以通过添加以下服务器来验证请求中cookie的存在。get()funcion之前的静态文件夹一般情况(假设您使用的是快速服务器):

server.get(['/assets/img/**','/assets/images/**'], (req, res, next) => {
    if(req.url == '/assets/images/logo*.*') {
      next();
    }
    console.log('requested image' + req.url);
    let maxage;
    if (!isBot(req)) {
      let cookieLang = req.cookies['my_cookie'];
      if (!cookieLang) {
        console.log('no cookie ');
        res.status(403);
        maxage = 5; // 5 seconds, in order not to damage your website visibility if viewer ends up visiting your site
        res.setHeader('Cache-Control', 'public, max-age='+maxage);
        res.setHeader('Expires', new Date(Date.now() + maxage * 1000).toUTCString());
        res.sendFile(join(distFolder + '/assets/images/logo.png'));
      } else {
        console.log('withcookie ' + cookieLang);
        res.set({'Cache-Control': 'max-age=31536000'});
        res.sendFile(join(distFolder + req.url));
      }
    } else {
      res.set({'Cache-Control': 'max-age=31536000'});
      res.sendFile(join(distFolder + req.url));
    }
  });
  server.get('*.*', express.static(distFolder, {
    maxAge: '1y'
  }));

在我的例子中,为了帮助我从热链接中获益,我返回了我们公司的徽标,而不是所请求的图像:o)但您可以什么也不返回。在这个例子中,我还使用了isBot()函数来检查用户代理,以便让WhatsApp、Twitter和其他机器人在这些社交网络中添加帖子链接时获得公司可见性所需的图像。
欢迎任何改进意见!

相关问题