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

UNREGISTERED_ON_API_CONSOLE при получении токена OAuth2 на Android

Мы находимся под Android (Jellybean и выше), и у нас есть приложение, которое должно использовать OAuth2 с Google для аутентификации.

Я упростил активность входа, но выглядит так:

AccountManager mAccountManager;
// [...]
Account account = new Account("[email protected]", "com.google");
// same with professional email managed by Google as [email protected]
// real code recovers accounts with mAccountManager.getAccountsByType("com.google")
mAccountManager = AccountManager.get(getBaseContext());
mAccountManager.getAuthToken(account, "oauth2:https://www.googleapis.com/auth/userinfo.email", null, MyActivity.this, new AccountManagerCallback<Bundle>() {
    @Override
    public void run(AccountManagerFuture<Bundle> accountManagerFuture) {
        try {
            String token = accountManagerFuture.getResult().getString(AccountManager.KEY_AUTHTOKEN);
            // exception occurs here
            // [...]
        } catch (Exception e) {
            Log.e("account", "exception occurs", e);
        }
    }
}, null);

Когда мы вызываем accountManagerFuture.getResult(), он вызывает это исключение:

android.accounts.AuthenticatorException: UNREGISTERED_ON_API_CONSOLE
    at android.accounts.AccountManager.convertErrorToException(AccountManager.java:2024)
    at android.accounts.AccountManager.access$400(AccountManager.java:144)
    at android.accounts.AccountManager$AmsTask$Response.onError(AccountManager.java:1867)
    at android.accounts.IAccountManagerResponse$Stub.onTransact(IAccountManagerResponse.java:69)
    at android.os.Binder.execTransact(Binder.java:446)

Я не могу найти ни документа об этом, ни других людей с тем же исключением, и я довольно смущен: вызов AccountManager.getAuthToken предоставляет только учетную запись (имя и тип), область действия и метод обратного вызова нет параметра для указания приложения или чего-то, что я мог бы настроить в консоли API-интерфейса dev.

Я уверен, что я что-то упустил, но что?

4b9b3361

Ответ 1

Хорошо, я, наконец, понял это. Не уверен, что я неправильно прочитал документацию или если отсутствуют ссылки, но в любом случае.

Факт заключается в том, что когда вы подписываете APK, а затем спрашиваете у Google токен OAuth2, вы должны зарегистрировать свое подписанное приложение через консоль dev. Это мера безопасности, основанная на имени пакета приложения и отпечатке sha1.

Для этого вам необходимо:

  • подпишите свой APK вручную или через Gradle или что-то еще: Документация по Android довольно понятна на этом шаг;
  • получите свой отпечаток sha1; как упоминается в этот SO ответ, это довольно просто на Android Studio: в на панели Gradle выберите задачу signingReport под вашим корневым проектом и запустите ее - на выходе будет отображаться отпечаток SHA1;
  • зарегистрируйте свой APK через Google dev console: создайте новый идентификатор клиента Credentials/OAuth/Android, определяемый полученным вами отпечатком SHA1 и вашим именем пакета APK.

И вуаля!

Для информации, единственная официальная документация, которую я нашел, объясняя, почему и как из двух заключительных шагов здесь: https://developers.google.com/drive/android/auth

Ответ 2

У вас нет репутации, чтобы прокомментировать принятый ответ...

Регистрация моего приложения в консоли google dev не работала для меня. Оказалось, что, поскольку я использовал отладочную конструкцию gradle, мне пришлось добавить ".debug" к имени пакета в консоли google dev.

Я нашел это, отладив код Android AccountManager. Когда я вступил в код, я заметил, что переменная для моего имени пакета приложений имела ".debug" в конце этого. Поэтому вместо использования фактического имени пакета "com.package.name" в консоли google dev я изменил его на "com.package.name.debug", который исправил исключение UNREGISTERED_ON_API_CONSOLE для меня.

Причина этого в том, что мой debug buildType в gradle имел "applicationIdSuffix".debug "'.

Ответ 3

Для тех, кто все еще борется с этим, вот что сработало для меня:

Если вы зарегистрируете свое приложение в программе Google Play App Signing, то ваш KeyStore не используется де-факто для подписания приложения после его поступления в магазин воспроизведения - поэтому отпечатки пальцев не совпадают.

Google удаляет ваш сертификат и создает новый сертификат подписи, который используется для подписания вашего APK.

В Play Console перейдите в Управление выпуском → Подписание подписки

Если вы выбрали Подписание подписки на Google Play, вы увидите там 2 сертификата вместе со всеми их отпечатками. Используйте Отпечаток сертификата подписки на приложение вместо Загрузить сертификат, который является вашим хранилищем ключей.

Ответ 4

Для меня решения выше не работают вообще. Я наконец выяснил ошибку сам. У меня есть несколько папок в моем рабочем пространстве, и каждый из них имеет свой собственный файл Manifest.xml, что означает, что у них есть разные имена пакетов. В этом случае, когда мы регистрируемся в Google API, мы должны использовать имя пакета в файле build.gradle, свойство applicationId. Тогда вот оно.

Ответ 5

Спасибо Xavier Portebois, ваш ответ действительно помог. Мне пришлось сделать еще два шага.

  • Убедитесь, что вы включили API для используемой вами службы (в моем случае API календаря) в той же самой консоли google dev
  • Если вы используете подписку на Google Play, вы не хотите использовать отладочный отпечаток SHA от Android Studio. Вместо этого перейдите в консоль публикации приложений → управление выпуском → подписка на приложение. Используйте отпечаток SHA-1 из сертификата подписи приложения. 2-я строка на этом скриншоте

Спасибо за информативный ответ!

Ответ 6

Для меня проблема заключалась в том, что отпечаток Signing-сертификата (SHA-1) отладочного приложения и приложение выпуска не совпадают, когда я обновляю приложение и меняю имя пакета. Я потратил дни, проверяя имя пакета, а затем выяснил, что проблема - это имя пакета.

Чтобы получить правильный ключ SHA-1, следуйте этому сообщению S.O, затем используйте этот ключ для создания нового идентификатора клиента OAuth для вашего приложения.