如何使 Nodejs express.js(代理)服务器仅适用于特定域?



我在node.js(expressjs)中开发了一个小图像代理。此代理应减少来自我的网站"www.myUrl.com"的所有图像。到目前为止,这也很好用。但我想保护代理免受未经授权的访问。 也就是说,一旦通过代理从另一个 url 加载图像,就会出现错误消息"未经授权"或空......是要归还的。 我已经尝试通过req.headers.origin读取标头"origin",但这是空的:

console.log(JSON.stringify(req.headers))显示了这一点:

{
"host":"myImageProxyUrl.com",
"user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/54.0.2840.100Safari/537.36","accept":"image/webp,image/*, */*; q=0.8",
"accept-encoding":"gzip, deflate, sdch, br",
"accept-language":"de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4",
"connection":"keep-alive",
"referer":"https://myUrl.de/myPage",
"x-forwarded-for":"ip1,ip2",
"x-forwarded-proto":"https, https",
"x-mod-original-region":"joyent-eu-ams-1.onmodulus.net",
"x-mod-region":"aws-us-east-1a.onmodulus.net"
}

代理托管在 modulus.io。 "www.myUrl.com"是一个流星.js应用程序。

如何使代理仅适用于域"www.myUrl.com"?

谢谢。

更新:

图像只是通过客户端中的图像标记加载:

<img src='http://myImageProxyUrl.com/imageXY.png' />

似乎最好使用 nginx 作为此类工作的反向代理。

通过在应用程序级别阻止访问,您正在浪费可能被合法请求使用的资源。如果您正在寻找生产解决方案,请避免在请求到达您的应用后阻止请求。

一个简单的例子是尝试DoSing您的网站,攻击者只需要垃圾邮件请求即可将您的应用程序减慢到爬行速度。Nginx允许您使用速率限制并减少发生此类事情的机会。

该技术与nginx相同,检查标题并阻止除具有正确引用者之外的所有内容。

引用过滤的配置如下所示:

location / {
if ($http_referer !~ "myurl.com"){
return 403
}
proxy_pass http://127.0.0.1:3000;  #replace 3000 by the port your app runs on
proxy_http_version 1.1;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;       
}

有很多关于如何使用nginx作为快速应用程序的反向代理的资源,这真的很简单。祝你好运!

如果我正确理解您的问题(不是很清楚),那么您希望禁止在您的代理在您自己的网站以外的其他网站上提供的图像的热链接。如果是这样,那么您需要检查引用标头。如果您的 Express 应用程序中有这样的路线:

app.get('/something', function (req, res, next) {
// some response
});

然后,您可以将其更改为:

app.get('/something', function (req, res, next) {
if ( checkReferer(req) ) {
// respond normally
} else {
// respond with error
}
});

实现checkReferer可以是这样的:

function checkReferer(req) {
var url = 'http://good.url.com/';
return req.get('Referer').indexOf(url) === 0;
}

或者,如果要允许使用没有引用标头的使用:

function checkReferer(req) {
var url = 'http://good.url.com/';
return !req.get('Referer') || req.get('Referer').indexOf(url) === 0;
}

如果根本没有 Referer 标头,则上述内容将起作用,但如果有,则必须以正确的 URL 开头。如果要添加更多域,或者要同时允许 example.com 和 www.example.com 等,则此功能可能需要变得更加复杂。重要的是,如果 Referer 可以满足您的要求,此函数应返回true,如果不符合,则返回false

更好的方法(感谢 xShirase 在注释中指出)是添加一个中间件而不是修改路由处理程序。这样,您就不必在很多地方复制该逻辑。例如:

app.use(function (req, res, next) {
if ( checkReferer(req) )
return next();
res.status(403).send('Forbidden');
});

(checkReferer与上面相同),然后路由处理程序没有变化:

app.get('/something', function (req, res, next) {
// some response
});
app.get('/something/else', function (req, res, next) {
// another response
});

最新更新