У меня возникли проблемы с получением единовременного кода авторизации от Google. Я пытаюсь получить код авторизации от клиента Android, чтобы я мог отправить его на мой бэкэнд Rails (веб-клиент).Получение одноразового кода авторизации Google
В моем Google Cloud Developer Console У меня есть приложение с двумя идентификаторами клиента:
идентификатор клиента для веба-приложений (для моих рельсов бэкэнда)
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 бэкэнда.
Как вы получаете автономный авторизационный код (access_type = offline) с помощью GoogleAuthUtil.getToken()? Вам удалось это сделать? – grebulon
@grebulon Да, я смог получить одноразовый код авторизации с помощью GoogleAuthUtil.getToken() после того, как все было принято в принятом ответе. Я отправил этот одноразовый код авторизации на наш серверный сервер, который использовал его для получения токена goi. – mikeorr85
Я почти заставляю его работать ... В моем потоке я продолжаю получать UserRecoverableAuthException (NeedPermission) для автономного разрешения. Запуск полученного намерения и вызов getToken снова запускает диалоговое окно добавления разрешений для автономного разрешения и т. Д. В бесконечном цикле. – grebulon