2016-11-29 2 views
2

Я разработал небольшой прокси изображений в node.js (expressjs). Этот прокси должен уменьшить все изображения, которые поступают с моего сайта «www.myUrl.com». Это также хорошо работает до сих пор. Но я хотел бы защитить прокси-сервер от несанкционированного доступа. То есть, как только изображение загружается через прокси из другого URL-адреса, должно быть возвращено сообщение об ошибке «unauthorized» или null .... я уже пытался прочитать заголовок «происхождение» через req.headers.origin, но это было пусто:Как я могу сделать сервер Nodejs express.js (proxy) доступным только для определенного домена?

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»?

Спасибо.

Update:

Изображение просто загружается поверх тега изображений в клиенте:

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

предоставляют метод аутентификации для доступа к прокси. Как и любой прокси-сервер, вызывающий URL-адрес, должен иметь некоторый токен, если нет, то его несанкционированный – AJS

+0

Но этот токен затем отображается на клиенте и может быть скопирован, правильно? – laren0815

+0

Для этого используйте некоторые методы шифрования, чтобы вы могли передавать зашифрованный токен. Или вы можете проверить заголовок запроса на своем сервере, как if (request.headers.host == 'www.myUrl.com') {продолжить} else {несанкционированное сообщение} – 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 и т. Д. Важно то, что эта функция должна возвращать true, если Referer подходит для вашего требования и 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

@xShirase Спасибо, что указали это. Я добавил его к ответу. – 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 в качестве обратного прокси-сервера для экспресс-приложение, это действительно просто. Удачи!