2016-11-29 40 views
2

我在node.js(expressjs)中開發了一個小圖像代理。這個代理應該減少來自我的網站「www.myUrl.com」的所有圖片。迄今爲止,這也很有效。但我希望保護代理免受未經授權的訪問。 也就是說,只要通過代理從另一個url加載圖像,就會返回錯誤消息「未授權」或null ...。 我已經嘗試通過req.headers.origin讀取頭「原點」,但這是空的:如何才能使Nodejs express.js(代理)服務器僅適用於特定域?

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」是一款Meteor.js應用程序。

如何讓代理僅適用於域名「www.myUrl.com」?

謝謝。

更新:

圖像只裝在客戶端的圖像標籤:

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

提供身份驗證方法來訪問代理服務器。像任何url調用代理服務器都必須有一些令牌,如果不是那麼它的未經授權 – AJS

+0

但是,這個令牌然後在客戶端可見,可以複製,對吧? – laren0815

+0

爲了使用某種加密技術,您可以傳遞加密的令牌。或者你可以檢查服務器上的請求標題,如if(request.headers.host =='www.myUrl.com'){繼續}其他{未授權消息} – AJS

回答

1

如果我正確理解你的問題(這是不是很清楚),那麼你要禁止熱將代理服務器上的圖像鏈接到您自己以外的其他網站上。如果是這樣,那麼你需要檢查Referer頭。如果你有你的快遞應用這樣的路線:

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; 
} 

或者,如果你想允許使用沒有Referer頭:

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 
}); 
+0

這就是我想要的,對不起我的英語。是否確定瀏覽器發送了「Referer」標題,或者某些人是否可能在我的網站上看不到任何圖片,例如使用IE時? – laren0815

+0

@rsp,如果在Express中執行它,中間件會更有效率,這是OP選擇的方式。你能把這個添加到你的答案嗎?不想偷你的雷霆;) – xShirase

+0

@xhirase謝謝你指出。我將它添加到答案中。 – rsp

2

好像你會更好使用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作爲快遞應用反向代理了大量的資源,這是很簡單的。祝你好運!

相關問題