HTTP-запрос не совпадает на Heroku и Google Cloud Run - PullRequest
0 голосов
/ 22 февраля 2020

У меня есть API-интерфейс NodeJS / ExpressJS, который выполняет HTTP-запрос для получения JSON перед отправкой ответа. Вот фрагмент кода:

const ipApiUrl = `https://ipapi.co/${ip}/json/`
const ipApiResponse = await axios.get(ipApiUrl)
console.log(ipApiResponse.data)
ipCountryCode = ipApiResponse.data.country_code

Этот код отлично работает локально. Он также отлично работает на Heroku. Тем не менее, он НЕ работает одинаково в Google Cloud Run.

Вот что ipApiResponse.data должно быть:

{
    "ip": "141.117.117.76",
    "city": "Toronto",
    "region": "Ontario",
    "region_code": "ON",
    "country": "CA",
    "country_code": "CA",
    ...
}

ОДНАКО, при отправке запроса из Google Cloud Run API, который я использую, возвращает что-то другое. Вместо этого я получаю ответ:

{ ip: '169.254.8.129', reserved: true }

Я думаю, что эта проблема связана либо с Google Cloud Run, либо с Docker, потому что у меня также есть проблемы с отправкой HTTP-запросов на другие сайты, такие как ipstack.com.

Я развертываю в Google Cloud Run с помощью Docker. Мой Dockerfile использует node:10 и предоставляет переменную окружения PORT, как сказано в документации. Все остальное работает отлично, за исключением этого HTTP-запроса. Я пробовал оба axios и fetch.

Ответы [ 2 ]

1 голос
/ 22 февраля 2020

Вы отправляете зарезервированный IP-адрес из частного IP-пространства. Этот адрес недействителен на сайте c Inte rnet. Возвращенный ответ от IPAPI правильный.

IP-адреса в блоке CIRD 169.254.0.0/16 называются Automati c Частный IP-адрес. Адрес в этом диапазоне обычно используется для локальных зарезервированных сетевых функций и для систем, которые автоматически назначают IP-адреса без DHCP-серверов в сети. Этот адрес также может быть назначен в результате сбоя сети.

Решение состоит в том, чтобы использовать действительный IP-адрес publi c в вашем запросе к IPAPI. Если ваш код обнаруживает этот адрес, значит у вас есть программная ошибка.

Примечание. Если вы пытаетесь определить IP-адрес службы Cloud Run, проверив сетевой интерфейс, вы не сможете. Cloud Run - это сервис, который работает за балансировщиками нагрузки и называется Global Frontend (GFE). Вам нужно будет использовать внешнюю службу, чтобы спросить, «каков мой publi c IP-адрес». Возвращенный IP-адрес будет для GFE, а не для вашей службы Cloud Run.

0 голосов
/ 26 февраля 2020

Чтобы найти IP-адрес посетителя в приложении Cloud Run, вам нужно прочитать заголовок X-Forwarded-For.

Когда вы просто посмотрите на IP-адрес в запросе или на TCP-соединение, вы увидите увидеть внутренний IP-адрес балансировщика нагрузки, который отправляет трафик c в ваше приложение. (169.254.xx - это внутреннее пространство IP-адресов, определенное в RF C 3927 , поэтому вы видите "reserved": true.)

Итак, в Express попробуйте выполнить :

var ip = req.header('X-Forwarded-For')
...