9

У меня возникли проблемы с получением единовременного кода авторизации от Google. Я пытаюсь получить код авторизации от клиента Android, чтобы я мог отправить его на мой бэкэнд Rails (веб-клиент).Получение одноразового кода авторизации Google

В моем Google Cloud Developer Console У меня есть приложение с двумя идентификаторами клиента:

  1. идентификатор клиента для веба-приложений (для моих рельсов бэкэнда)

  2. ID клиента для Android приложения (для моих android client). SHA1 используется из ~/.android/debug.keystore

Предположим, клиент веб-приложений идентификатор 12345.apps.googleusercontent.com

Пусть Android ID клиента является 67890.apps.googleusercontent.com

Это часть моего кода :

private final static String WEB_CLIENT_ID = "12345.apps.googleusercontent.com"; 
private final static String GOOGLE_CALENDAR_API_SCOPE = "audience:server:client_id:" + WEB_CLIENT_ID; 

private void getAndUseAuthToken(final String email) { 
     AsyncTask task = new AsyncTask<String, Void, String>() { 
      @Override 
      protected String doInBackground(String... emails) { 
       try { 
        return GoogleAuthUtil.getToken(AddExternalCalendarsActivity.this, emails[0], GOOGLE_CALENDAR_API_SCOPE); 
       } catch (UserRecoverableAuthException e) { 
        startActivityForResult(e.getIntent(), IntentConstants.REQUEST_GOOGLE_AUTHORIZATION); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } catch (GoogleAuthException e) { 
        e.printStackTrace(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 

       return null; 
      } 

      @Override 
      protected void onPostExecute(String authToken) { 
       if (authToken != null) { 
        saveTokenAndGetCalendars(email, authToken); 
       } 
      } 
     }; 

     String[] emails = new String[1]; 
     emails[0] = email; 
     task.execute(emails); 
    } 

Некоторые дополнительные замечания

  • Я ударять GoogleAuthException и прием «Unknown», как подробно сообщения

  • Я не может добавить дополнительные элементы в разрешениях Google Cloud Console для этого проекта - при добавлении новый член появляется всплывающее окно с «Ошибка сервера. Упс! . Наш плохо ". Я послал в обратную связь Google дважды

  • Я имею в виду эту documentation Обратите внимание на цитату ниже К...„Фиксированные“, они говорят, что мне не нужно предварять аудиторию: сервер : client_id в моей переменной GOOGLE_CALENDAR_API_SCOPE Я попытался с и без и по-прежнему получать тот же GoogleAuthException

в этой ситуации Android приложение может вызвать метод GoogleAuthUtil.getToken() на. от имени любой из учетных записей Google на устройстве, nd со значением аргумента области аудитория: server: client_id: 9414861317621.apps.googleusercontent.com. Аудитория префикса: server: client_id: исправлена, а остальная часть строки области является идентификатором клиента веб-компонента.

  • Если я использую эту область, я могу проверить подлинность с помощью Google из устройства.Однако прочитанная документация предполагает, что мне нужно использовать идентификатор веб-клиента сервера (который находится в том же проекте консоли Google как идентификатор клиента android) в области, чтобы сервер мог попасть в google api от имени пользователь, который уполномочил его на андроид клиента:

    private final static String GOOGLE_CALENDAR_API_SCOPE = "oauth2:https://www.googleapis.com/auth/calendar";

UPDATE 1

первоначально я добавил в ответ: причина моей первой проблемы - я поражающего GoogleAuthException а также получение «Неизвестно» в качестве детали сообщения - было ошибкой, которую я сделал при добавлении идентификатора клиента Android в облачную консоль. SHA1 был правильным, но я неправильно набрал имя пакета. Я использовал com.company.app, когда мой пакет android на самом деле com.company.android.app. Код в исходном вопросе отлично работает. Просто убедитесь, что у вас есть все необходимые клиенты в проекте Google Cloud Console.

Но еще одна проблема все еще существует. Когда я посылаю маркер авторизации одноразового вернулся из GoogleAuthUtil.getToken() к бэкэнду Rails, а затем попытаться обменять его для access_token и refresh_token, я получаю последующий:

Signet::AuthorizationError: 
    Authorization failed. Server message: 
    { 
     "error" : "invalid_grant" 
    } 

Это google documentation и несколько сообщений SO указывают, что мне нужно установить access_type=offline. Но я думаю, что это когда вы запрашиваете одноразовый код авторизации и автономный доступ с веб-сервера. Я пытаюсь запросить одноразовый код авторизации с Android-клиента и отправить его на веб-сервер.

Возможно ли это с GoogleAuthUtil.getToken()?

UPDATE 2

Google Plus Логин должен быть в объеме, даже если вы только пытаетесь получить доступ к календарю:

private final static String GOOGLE_CALENDAR_API_SCOPE = "oauth2:server:client_id:" + WEB_CLIENT_ID + ":api_scope:https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/calendar"; 

Это SO post было полезно. Кроме того, Google's Cross Client identity documentation не укажет:

[Примечание: эта политика постепенно выкатывается. На данный момент, когда участвуют маркеры доступа, она применяется только тогда, когда запрашиваемые объемы включают https://www.googleapis.com/auth/plus.login.]

Я резюмировать в ответ, если маркер обмена работает на Rails бэкэнда.

+0

Как вы получаете автономный авторизационный код (access_type = offline) с помощью GoogleAuthUtil.getToken()? Вам удалось это сделать? – grebulon

+0

@grebulon Да, я смог получить одноразовый код авторизации с помощью GoogleAuthUtil.getToken() после того, как все было принято в принятом ответе. Я отправил этот одноразовый код авторизации на наш серверный сервер, который использовал его для получения токена goi. – mikeorr85

+0

Я почти заставляю его работать ... В моем потоке я продолжаю получать UserRecoverableAuthException (NeedPermission) для автономного разрешения. Запуск полученного намерения и вызов getToken снова запускает диалоговое окно добавления разрешений для автономного разрешения и т. Д. В бесконечном цикле. – grebulon

ответ

3

Две вещи решил это для меня:

  1. Убедитесь, что Идентификаторы Android и веб-клиентов настроены правильно в том же проекте Google Cloud Console.

  2. Используйте правильный объем. Кроме того Войти требуется, даже если вы только получить доступ к API Календаря:

    // идентификатор веб-сервер, который обменивается код аутентификации для доступа и обновить маркеры

    частной окончательной статической строку WEB_CLIENT_ID = «12345 .apps.googleusercontent.com "; закрытый конечный статический String GOOGLE_CALENDAR_API_SCOPE = "oauth2: server: client_id:" + WEB_CLIENT_ID + ": api_scope: https://www.googleapis.com/auth/plus.loginhttps://www.googleapis.com/auth/calendar";

0

Вот что я сделал:

final String authToken = GoogleAuthUtil.getTokenWithNotification (this.context, account.name, "oauth2:" + AuthUtils.profileScope, new Bundle(), 
       Contract.authority, new Bundle()); 

Но вы равнину getToken должны работать одинаково для переднего плана деятельности.

Возьмите этот токен, отправьте его на сервер так, как вы можете использовать его, как HTTP-заголовок (через HTTPS). Пока область действия сервера является подмножеством области, используемой для получения токена, у вас не должно быть проблем. Сервер использует идентификатор сервера, а клиент android использует идентификатор клиента android.

Вы должны установить масштаб либо:

oauth2:https://www.googleapis.com/auth/calendar 

или

oauth2:https://www.googleapis.com/auth/calendar.readonly 

См https://developers.google.com/google-apps/calendar/auth

Edit: Хорошо, я вижу, что вы пытаетесь сделать. Значение Прицел список разделенных пробелами, так что вы, вероятно, необходимо будет приложить аудиторию: сервер: client_id: до сферы, как:

"oauth2:https://www.googleapis.com/auth/calendar audience:server:client_id:12345-your-web-component-client-id" 
+0

Спасибо за ответ. В приведенной выше области возвращается свойство GoogleAuthException - «INVALID_SCOPE». Я думаю, это связано с тем, что Google только один раз требует авторизации от клиентов в одном проекте. Я * думаю * вот что они говорят [здесь] (https://developers.google.com/accounts/docs/CrossClientAuth) – mikeorr85

Смежные вопросы