Подтвердить что ты не робот

Как ограничить доступ к API конечных точек Google App Engine только для моих приложений для Android?

Я - разработчик Android, создающий свой первый интерфейс для Google App Engine (java) для своих приложений. Я не хочу, чтобы кто-либо еще обращался к этому API, кроме моего приложения. (Я планирую использовать App Engine для проверки покупок InApp в моем приложении для Android). Мои данные не имеют отношения к пользователям, поэтому, Я не хочу, чтобы пользователи имели доступ к моему API, даже если они вошли в систему со своими учетными записями Google (на веб-устройствах или устройствах Android).

Я выполнил следующие шаги: "Указание авторизованных клиентов в интерфейсе API" (https://developers.google.com/appengine/docs/java/endpoints/auth) например, генерировать идентификаторы клиентов и добавлять их в @Api (clientIds и аудитория) кроме "Добавить параметр пользователя" - поскольку мне не нужна аутентификация пользователя.

Затем я развернул движок приложения, и я все еще могу получить доступ к API через API-обозреватель (https://your_app_id.appspot.com/_ah/api/explorer) (Я не добавил идентификатор клиента API_EXPLORER)

Я тестировал APK, который был создан с использованием конечных библиотек, перед добавлением идентификаторов клиентов и все еще мог получить доступ к API.

  • Добавляет ли пользовательский параметр ко всем API конечных точек? для достижения моей цели (ограничьте API только моими приложениями для Android).

  • Могу ли я передать null как имя userAccount из Android-клиента и игнорировать значение параметра пользователя на сервере (так как это будет null)? Будет ли это гарантировать, что API доступен только из моих приложений для Android (поскольку идентификатор клиента генерируется для моего имени пакета и SHA1 APK?)

  • Должен ли я использовать что-то вроде учетной записи службы для этой цели?

В документации для Android, необходимо добавить идентификаторы Android и Web-клиентов, а аудитория должна быть такой же, как идентификатор веб-клиента. Открывает ли этот доступ любой другой веб-клиент? могу ли я пропустить упоминание идентификатора веб-клиента и все еще достичь своей цели?

Цените свое время и помощь.

...... обновление с моим дальнейшим исследованием...

Я сделал следующее:

  • Добавлен пользовательский параметр для API-интерфейсов на бэкэнд - но не проверял нулевое значение. API все еще можно получить без прохождения каких-либо учетных данных (от Android отладки APK и API-браузера)

  • Затем я попробовал

    mCredential = GoogleAccountCredential.usingAudience(это, "server: client_id:" + WEB_CLIENT_ID); mCredential.setSelectedAccountName(нуль);

и передал эти учетные данные строителю API (как предложено в некоторых других сообщениях) Причиненный FATAL EXCEPTION. Таким образом, мы не можем передавать имя нулевой учетной записи.

  • Я мог бы назвать API с помощью API-обозревателя без OAuth. Но когда я включил OAuth, он дал ошибку, заявив, что этот идентификатор клиента не разрешен! (Я еще не добавил com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID в client_ids {})

  • Затем я добавил код для вывода OAuthRequestException на бэкэнд, если пользователь имеет значение NULL. Это привело к тому, что API-браузер получал ошибки без OAuth. Он работает с OAuth включен после добавления API_EXPLORER_CLIENT_ID в client_ids)

  • Добавлен код для передачи действительного имени учетной записи пользователя (электронной почты) из моего приложения для Android. Затем я могу получить доступ к API только с моей версией APK. Даже отладчик APK получает исключения! - вот что я ожидал. Итак, я полагаю, что никакие другие приложения для Android не смогут получить доступ к этому API.

Итак, не проверка нулевого пользователя на API-интерфейсе - это плохая идея (как предложено в других сообщениях). Это так же хорошо, как не упоминание каких-либо client_id и отсутствие параметра пользователя.

Только вопрос, который у меня есть в данный момент: Если кто-то может определить WEB_CLIENT_ID из APK, смогут ли они использовать его для создания веб-клиента для доступа к моему API (я не упоминал секрет клиента в любом месте код. Поэтому я думаю, что это невозможно).


Я искал группы Google и Stackoverflow, но все еще не ясно.

4b9b3361

Ответ 1

У меня была аналогичная проблема, но не между Android и App Engine, а между отдельным сервером и App Engine. То, как я справлялся с этим, заключалось в том, чтобы добавить хэш-поле сигнатуры в качестве параметра для каждого вызова API. Если запрос имел неправильную подпись, ему будет отказано.

Например, предположим, что конечная точка API example.com/api/do_thing?param1=foo. Я хотел бы получить весь URL вместе с секретным ключом, а затем добавить результат хэша к запросу: example.com/api/do_thing?param1=foo&hash=[some long hex value].

Затем, на стороне сервера, я сначала удалю хэш из запроса url, а затем запустил хэш на все оставшееся. Наконец, вы проверяете, соответствует ли рассчитанный хеш тот, который был отправлен с запросом, а если нет, вы можете отклонить запрос.

Однако очень важно, чтобы ваш секретный ключ оставался секретным. Вы должны быть осторожны с этим на Android, потому что кто-то может попытаться декомпилировать APK.

Ответ 2

Обращаясь к той же проблеме, что и вам! Аутентификация конечной точки Android без учетной записи Google User просто невозможна!

Итак, вот мой способ решить эту проблему без какого-либо взаимодействия с пользователем (возможно, это неправильно, но это работает, и у вас есть сильная аутентификация (SHA1 + учетная запись Google)):

ЗДЕСЬ МОЙ АНДРОИДНЫЙ КОД

Получить и построить действительный учетный документ

  //Get all accounts from my Android Phone
         String validGoogleAccount = null;
         Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
         Account[] accounts = AccountManager.get(context).getAccounts();
         for (Account account : accounts) {
             if (emailPattern.matcher(account.name).matches()) {
                 //Just store mail if countain gmail.com
                 if (account.name.toString().contains("gmail.com")&&account.type.toString().contains("com.google")){
                     validGoogleAccount=account.name.toString();
                 }

             }
         }

        //Build Credential with valid google account
        GoogleAccountCredential credential = GoogleAccountCredential.usingAudience(this,"server:client_id:301991144702-5qkqclsogd0b4fnkhrja7hppshrvp4kh.apps.googleusercontent.com");
        credential.setSelectedAccountName(validGoogleAccount);

Использовать эти учетные данные для защищенных вызовов

Campagneendpoint.Builder endpointBuilder = new Campagneendpoint.Builder(AndroidHttp.newCompatibleTransport(), new JacksonFactory(), credential);

ЗДЕСЬ МОЙ КОД ПОДКЛЮЧЕНИЯ API: Аннотации API

@Api(
        scopes=CONSTANTES.EMAIL_SCOPE,
        clientIds = {CONSTANTES.ANDROID_CLIENT_ID, 
                     CONSTANTES.WEB_CLIENT_ID,
                     com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID},
        audiences = {CONSTANTES.ANDROID_AUDIENCE},      
        name = "campagneendpoint",
        version = "v1"
     )

Код метода:

public Collection<Campagne> getCampagnes(@Named("NumPortable")String NumPortable, User user) throws  UnauthorizedException {
        if (user == null) throw new UnauthorizedException("User is Not Valid");

      return CampagneCRUD.getInstance().findCampagne(NumPortable);
     }

На данный момент он работает только на Android (я не знаю, как мы будем делать на IOS..)..

Надеюсь, это поможет вам!

Ответ 3

Google предоставляет способы сделать это для Android, web и iOS Этапы включают в себя:

  • Указание идентификатора клиента для приложений, которые вы хотите разрешить для запросов в свой API.
  • Добавление параметра пользователя ко всем открытым методам, которые должны быть защищены с помощью авторизации.
  • Создание клиентской библиотеки снова для любых Android-клиентов
  • Повторное развертывание вашего backend API.
  • Обновление обновленного файла jar в Android-проекте для вашего Android-клиента.

Эти шаги подробно изложены в Google Использование Auth с конечными точками, а также на этом blog

Ответ 4

Опираясь на ту же проблему, вот результат моих исследований:

  • Добавлен идентификатор cliend Android с отпечатком SHA1 в консоли Google.
  • Использование этого в аннотации API

НО:

  • Если я не добавляю параметр пользователя к методам: проверка идентификатора клиента приложения Android не работает

  • Если я добавлю параметр USER, но не прошу пользователя выбрать его учетную запись google для создания учетных данных... также он не работает...

Заключение: Кажется, необходимо подключить учетную запись пользователя для проверки идентификатора клиента приложения, который будет выполнен... Я действительно не понимаю, почему, поскольку между двумя процессами нет связи

Ответ 5

Доступ к этому сайту

Выберите проект, перейдите в раздел учетных данных

Создайте новый ключ api

Создайте новый ключ для Android

Нажмите "Редактировать разрешенные приложения для Android" и введите свой ключ SHA1; ваше имя пакета Android

Сообщите мне, если это решает проблемы.