Ошибка авторизации Flutter Google Places API

У меня есть приложение Flutter, которое использует Карты Google для отображения карт и выполнения вызовов API-интерфейса Places для поиска ближайших магазинов на основе местоположения пользователя. Во время разработки я не ограничивал ключи API, но теперь, когда я хочу перейти к производству, я ограничил ключи как для Android, так и для iOS.

Вот как я вызываю Places API:

final String apiUrl =
    "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${cords.latitude}%2C${cords.longitude}&radius=$radius&type=$type&key=$apiKey";
final response = await http.get(Uri.parse(apiUrl));

Я пытался ограничить ключи API для iOS и Android (по одному ключу для каждого приложения). Карта отображается правильно, но вызовы API мест возвращают следующую ошибку:

{
   "error_message" : "This IP, site or mobile application is not authorized to use this API key. Request received from IP address x.x.x.x, with empty referer",
   "html_attributions" : [],
   "results" : [],
   "status" : "REQUEST_DENIED"
}

После довольно долгого поиска я нашел сообщение о переполнении стека, в котором говорилось, что некоторые API-интерфейсы карт Google предназначены для вызова из внутренней системы, а не непосредственно из внешнего интерфейса. Вот ссылка на пост для справки: Android Google Maps Direction Api — ограничение ключа API не работает

Это заставило меня задуматься, возможно, то же самое произойдет и со мной. Судя по предоставленной пользователем ссылке, оказывается, что это действительно так... (Пожалуйста, дайте мне знать, если я ошибаюсь)

Какие ключи или учетные данные следует использовать для разных продуктов Карт?

Я подумываю изменить способ вызова API Places. Поскольку я уже использую Firebase, я подумываю о запуске облачной функции для вызова API-интерфейса Places, а затем о пересылке ответа JSON на клиентский телефон. Однако я не уверен, следует ли мне ограничивать ключ API для облачной функции.

Мои вопросы:

  • Верны ли мои доводы в пользу переключения на облачную функцию для вызова API Places на основании предоставленного сообщения о переполнении стека?
  • Должен ли я ограничить ключ API для облачной функции, учитывая соображения безопасности?

Если вы считаете, что я могу решить эту проблему другим способом, дайте мне знать. Я также заметил в таблице записи для Places SDK для Android и iOS, которые можно ограничить приложением, но я не знаю, подходит ли это для моего случая. потому что я использую флаттер.

Что следует уточнить:

  • ключ правильный, он работает, когда я отключаю ограничения
  • оплата включена
  • API мест также включен
  • Осталась квота

Любые предложения или идеи будут с благодарностью приняты. Заранее спасибо.

Просто чтобы убедиться, что я правильно понимаю, используете ли вы один и тот же ключ API для загрузки карты и запроса к Places API для каждой платформы?

Yrll 29.03.2024 04:47

Да, 1 ключ API для Android, он предназначен для SDK карт Android, а затем для вызовов API мест и еще один для ios.

Anthony Kalampogias 29.03.2024 08:03

Спасибо за разъяснение! В этом случае я бы посоветовал вам использовать отдельные ключи API также для запроса Places API и для загрузки карт. Вам не следует беспокоиться о наличии нескольких ключей API (максимум 300 ключей), поскольку это на самом деле считается хорошей практикой, поскольку вы можете отслеживать каждый ключ API в консоли. Также обратите внимание, что ограничение приложений для iOS и Android не позволит ключу API получать запросы к веб-службам. Таким образом, выполнение запроса веб-сервисов на стороне сервера является правильным.

Yrll 29.03.2024 08:10

Веб-сервисы (в данном случае API-интерфейс Places) можно использовать только с ключами API с ограничением по IP-адресу. Затем вы можете использовать прокси-сервер для запроса веб-сервисов, чтобы еще больше его защитить: Developers.google.com/maps/…

Yrll 29.03.2024 08:13

Если вы не можете получить уникальный IP-адрес в облачной функции, по крайней мере, ваш код будет работать в среде, в которой злоумышленники не смогут скомпрометировать ваш ключ API. Тем не менее, я бы, по крайней мере, ограничил использование ключа конкретными API-интерфейсами (в случае, если в проекте включены другие), а затем не использовал бы тот же ключ где-либо еще.

miguev 25.04.2024 13:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
175
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В конечном итоге я использовал вызываемую облачную функцию, поскольку я уже использовал Firebase и реализовал проверку приложений, чтобы убедиться, что только мои приложения могут запускать эту функцию, а также для обеспечения безопасности ключа API я использовал диспетчер секретных служб Google Cloud.

Это также хорошая практика, и предлагается ограничить ее конкретными API, которые вы хотите использовать.

Для всех, кто интересуется защитой конфиденциальной информации, Cloud Functions for Firebase интегрируется с Google Cloud Secret Manager.

https://firebase.google.com/docs/functions/config-env?gen=2nd#create-secret

export const fetchFromGoogleMaps = functions.onCall({
  secrets: ["secret_name"],
  enforceAppCheck: true,
}, async (request) => {
  const apiKey = process.env.secret_name;

  const apiUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude}%2C${longitude}&radius=${radius}&type=${type}&key=${apiKey}`;

  return await axios.default.get(apiUrl).then((apiResponse) => {
    // ...
  }).catch((error) => {
    // handle the error
  });

Другие вопросы по теме