invalid_grant пытается получить токен oAuth из google

Я продолжаю получать ошибку invalid_grant при попытке получить токен oAuth от Google для подключения к своим контактам api. Вся информация верна, и я трипл проверил это так, как будто это было в тупике.

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

Я столкнулся с этой проблемой, когда я явно не запрашивал «автономный» доступ при отправке пользователя в OAuth «Вы хотите, чтобы это разрешение приложения касалось ваших вещей?» стр.

Убедитесь, что в запросе указывается access_type = offline.

Подробности здесь: https://developers.google.com/accounts/docs/OAuth2WebServer#offline

(Кроме того: я думаю, Google добавил это ограничение в конце 2011 года. Если у вас есть старые токены до этого, вам нужно будет отправить своих пользователей на страницу разрешений, чтобы разрешить автономное использование.)

Я столкнулся с этой же проблемой, несмотря на указание «offline» access_type в моем запросе в соответствии с ответом bonkydog. Короче говоря, я нашел, что описанное здесь решение сработало для меня:

https://groups.google.com/forum/#!topic/google-analytics-data-export-api/4uNaJtquxCs

По сути, когда вы добавляете клиента OAuth2 в консоль Google API, Google предоставит вам «Идентификатор клиента» и «Адрес электронной почты» (при условии, что вы выбрали «webapp» в качестве вашего типа клиента). И, несмотря на вводящие в заблуждение соглашения об именах Google, они ожидают, что вы отправите «Адрес электронной почты» в качестве значения параметра client_id при доступе к их API OAuth2.

Это применимо при вызове обоих этих URL:

Обратите внимание, что вызов первого URL-адреса будет успешным, если вы вызываете его с помощью своего «Идентификатора клиента» вместо вашего «Адрес электронной почты». Однако использование кода, возвращенного с этого запроса, не будет работать при попытке получить токен-носитель со второго URL-адреса. Вместо этого вы получите сообщение об ошибке «Ошибка 400» и «invalid_grant».

Хотя это старый вопрос, кажется, что многие все еще сталкиваются с этим – мы провели несколько дней подряд, отслеживая это сами.

В спецификации OAuth2 «invalid_grant» является своего рода уловкой всех ошибок, связанных с недействительными / истекшими / отозванными токенами (токен предоставления или обновления).

Для нас проблема была вдвойне:

  1. Пользователь активно отменил доступ к нашему приложению
    Имеет смысл, но получите следующее: через 12 часов после отзыва Google перестает отправлять сообщение об ошибке в ответ: “error_description” : “Token has been revoked.”
    Это довольно вводит в заблуждение, потому что вы будете считать, что сообщение об ошибке всегда присутствует, и это не так. Вы можете проверить, имеет ли ваше приложение доступ на странице разрешения приложений .

  2. Пользователь сбросил / восстановил свой пароль Google
    В декабре 2015 года Google изменил свое поведение по умолчанию, чтобы сбрасывать пароль для пользователей, не являющихся пользователями Google Apps, автоматически отменяет все токены пользователей, обновляющие токены. При отзыве сообщение об ошибке следует тому же правилу, что и раньше, поэтому вы получите только «error_description» в течение первых 12 часов. Кажется, нет никакого способа узнать, был ли пользователь вручную отменен доступ (намеренный), или это произошло из-за сброса пароля (побочный эффект).

Кроме того, существует множество других потенциальных причин, которые могут вызвать ошибку:

  1. Серверные часы / время не синхронизированы
  2. Не разрешено для автономного доступа
  3. Изменено Google
  4. Использование истекших токенов обновления
  5. Пользователь неактивен в течение 6 месяцев
  6. Использовать электронную почту службы поддержки вместо идентификатора клиента
  7. Слишком много токенов доступа за короткое время
  8. Клиентский SDK может быть устаревшим
  9. Неверный / неполный токен обновления

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

Я столкнулся с той же проблемой. Для меня я исправил это, используя адрес электронной почты (строка, которая заканчивается на … @ developer.gserviceaccount.com) вместо идентификатора клиента для значения параметра client_id. Именование, установленное Google, вводит в заблуждение.

У меня было такое же сообщение об ошибке «invalid_grant», и это потому, что сообщение authResult [‘code’] с javascript на стороне клиента было получено неправильно на сервере.

Попробуйте вернуть его с сервера, чтобы убедиться, что это правильно, а не пустая строка.

Моя проблема заключалась в том, что я использовал этот URL:

 https://accounts.google.com/o/oauth2/token 

Когда я должен был использовать этот URL-адрес:

 https://www.googleapis.com/oauth2/v4/token 

Это было тестирование учетной записи службы, для которой был нужен автономный доступ к движку хранилища .

если вы используете библиотеку scribe, просто настройте автономный режим, например, bonkydog предлагает здесь код:

 OAuthService service = new ServiceBuilder().provider(Google2Api.class).apiKey(clientId).apiSecret(apiSecret) .callback(callbackUrl).scope(SCOPE).offline(true) .build(); 

https://github.com/codolutions/scribe-java/

на этом сайте console.developers.google.com

эта консольная плата выбирает ваш проект, вводя URL-адрес присяги. oauth callback url будет перенаправлять, когда успех oauth

Используя клиент clientId для Android (no client_secret), я получал следующий ответ об ошибке:

 { "error": "invalid_grant", "error_description": "Missing code verifier." } 

Я не могу найти документацию для поля «code_verifier», но я обнаружил, что если вы установите равные значения в запросах авторизации и токена, это приведет к удалению этой ошибки. Я не уверен, какой должна быть предполагаемая стоимость, или если она должна быть безопасной. Он имеет минимальную длину (16 символов), но я обнаружил, что параметр null также работает.

Я использую AppAuth для запроса авторизации в своем Android-клиенте, который имеет функцию setCodeVerifier() .

 AuthorizationRequest authRequest = new AuthorizationRequest.Builder( serviceConfiguration, provider.getClientId(), ResponseTypeValues.CODE, provider.getRedirectUri() ) .setScope(provider.getScope()) .setCodeVerifier(null) .build(); 

Вот пример запроса токена в узле:

 request.post( 'https://www.googleapis.com/oauth2/v4/token', { form: { 'code': '4/xxxxxxxxxxxxxxxxxxxx', 'code_verifier': null, 'client_id': 'xxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com', 'client_secret': null, 'redirect_uri': 'com.domain.app:/oauth2redirect', 'grant_type': 'authorization_code' } }, function (error, response, body) { if (!error && response.statusCode == 200) { console.log('Success!'); } else { console.log(response.statusCode + ' ' + error); } console.log(body); } ); 

Я тестировал, и это работает как с https://www.googleapis.com/oauth2/v4/token и с https://accounts.google.com/o/oauth2/token .

Если вместо этого вы используете GoogleAuthorizationCodeTokenRequest :

 final GoogleAuthorizationCodeTokenRequest req = new GoogleAuthorizationCodeTokenRequest( TRANSPORT, JSON_FACTORY, getClientId(), getClientSecret(), code, redirectUrl ); req.set("code_verifier", null); GoogleTokenResponse response = req.execute(); 

Это глупый ответ, но проблема для меня заключалась в том, что я не понял, что мне уже был выпущен активный токен OAuth для моего пользователя Google, которого я не смог сохранить. Решение в этом случае – перейти на консоль api и сбросить секрет клиента.

Есть много других ответов на SO для этого эффекта, например Reset Client Secret OAuth2 – Нужно ли клиентам повторно предоставлять доступ?

Возможно, вам придется удалить устаревший / недействительный ответ OAuth.

Кредит: node.js ошибка google oauth2 перестала работать invalid_grant

Примечание . Ответ на OAuth также станет недействительным, если пароль, используемый в первоначальной авторизации, был изменен.

Если в среде bash вы можете использовать следующее, чтобы удалить устаревший ответ:

rm /Users//.credentials/

Существуют две основные причины ошибки invalid_grant, которые вы должны позаботиться до запроса POST для обновления токена и токена доступа.

  1. Заголовок запроса должен содержать «content-type: application / x-www-form-urlencoded»
  2. Ваша полезная нагрузка запроса должна быть закодирована в форме данных формы, не отправлять как объект json.

В RFC 6749 OAuth 2.0 определяется значение invalid_grant как: предоставленный разрешающий разрешение (например, код авторизации, учетные записи владельца ресурса) или токен обновления недействителен, истек, отменен, не соответствует URI перенаправления, используемому в запросе авторизации, или был выдан другому клиенту ,

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

https://blog.timekit.io/google-oauth-invalid-grant-nightmare-and-how-to-fix-it-9f4efaf1da35

Рассмотрев и попробовав все другие способы здесь, вот как я решил проблему в nodejs с модулем googleapis вместе с модулем request , который я использовал для извлечения токенов вместо предоставленного getToken() :

 const request = require('request'); //SETUP GOOGLE AUTH var google = require('googleapis'); const oAuthConfigs = rootRequire('config/oAuthConfig') const googleOAuthConfigs = oAuthConfigs.google //for google OAuth: https://github.com/google/google-api-nodejs-client var OAuth2 = google.auth.OAuth2; var googleOAuth2Client = new OAuth2( process.env.GOOGLE_OAUTH_CLIENT_ID || googleOAuthConfigs.clientId, process.env.GOOGLE_OAUTH_CLIENT_SECRET || googleOAuthConfigs.clientSecret, process.env.GOOGLE_OAUTH_CLIENT_REDIRECT_URL || googleOAuthConfigs.callbackUrl); /* generate a url that asks permissions for Google+ and Google Calendar scopes https://developers.google.com/identity/protocols/googlescopes#monitoringv3*/ var googleOAuth2ClientScopes = [ 'https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/userinfo.email' ]; var googleOAuth2ClientRedirectURL = process.env.GOOGLE_OAUTH_CLIENT_REDIRECT_URL || googleOAuthConfigs.callbackUrl; var googleOAuth2ClientAuthUrl = googleOAuth2Client.generateAuthUrl({ access_type: 'offline', // 'online' (default) or 'offline' (gets refresh_token) scope: googleOAuth2ClientScopes // If you only need one scope you can pass it as string }); //AFTER SETUP, THE FOLLOWING IS FOR OBTAINING TOKENS FROM THE AUTHCODE const ci = process.env.GOOGLE_OAUTH_CLIENT_ID || googleOAuthConfigs.clientId const cs = process.env.GOOGLE_OAUTH_CLIENT_SECRET || googleOAuthConfigs.clientSecret const ru = process.env.GOOGLE_OAUTH_CLIENT_REDIRECT_URL || googleOAuthConfigs.callbackUrl var oauth2Client = new OAuth2(ci, cs, ru); var hostUrl = "https://www.googleapis.com"; hostUrl += '/oauth2/v4/token?code=' + authCode + '&client_id=' + ci + '&client_secret=' + cs + '&redirect_uri=' + ru + '&grant_type=authorization_code', request.post({url: hostUrl}, function optionalCallback(err, httpResponse, data) { // Now tokens contains an access_token and an optional refresh_token. Save them. if(!err) { //SUCCESS! We got the tokens const tokens = JSON.parse(data) oauth2Client.setCredentials(tokens); //AUTHENTICATED PROCEED AS DESIRED. googlePlus.people.get({ userId: 'me', auth: oauth2Client }, function(err, response) { // handle err and response if(!err) { res.status(200).json(response); } else { console.error("/google/exchange 1", err.message); handleError(res, err.message, "Failed to retrieve google person"); } }); } else { console.log("/google/exchange 2", err.message); handleError(res, err.message, "Failed to get access tokens", err.code); } }); 

Я просто использую request чтобы сделать запрос api через HTTP, как описано здесь: https://developers.google.com/identity/protocols/OAuth2WebServer#offline

 POST /oauth2/v4/token HTTP/1.1 Host: www.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=8819981768.apps.googleusercontent.com& client_secret={client_secret}& redirect_uri=https://oauth2.example.com/code& grant_type=authorization_code 

Попробуйте изменить свой URL для

 https://www.googleapis.com/oauth2/v4/token 
Давайте будем гением компьютера.