неверный грант пытаются получить OAuth-токен с Google



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



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

818   15  

15 ответов:

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

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

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

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

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

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-адреса. Вместо этого вы получите сообщение "Error 400" и "invalid_grant".

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

в спецификации OAuth2 "invalid_grant" является своего рода уловкой для всех ошибок, связанных с недопустимыми/истекшими/отозванными токенами (auth grant или refresh token).

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

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

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

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

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

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

Я столкнулся с той же проблемой. Для меня, я исправил это с помощью адреса электронной почты (строка, которая заканчивается [email protected]) вместо идентификатора клиента для значения параметра 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/

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

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

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

Я использую AppAuth для запроса авторизации в моем клиенте Android, который имеет :

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

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

существует множество других ответов на этот вопрос, например сбросить секрет клиента OAuth2-нужно ли клиентам повторно предоставлять доступ?

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

фото: узел.пример с JS в Google OAuth2, которые перестали работать invalid_grant в

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

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

rm /Users/<username>/.credentials/<authorization.json>

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

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

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

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

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

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

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

после рассмотрения и пробовать все другие способы здесь, вот как я решил проблему в 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

Comments

  1. Robdkz
    Robdkz 2 года назад
    In today's fast-paced world, staying informed about the latest advancements both domestically and globally is more vital than ever. With a plethora of news outlets vying for attention, it's important to find a trusted source that provides not just news, but analyses, and stories that matter to you. This is where <a href="https://www.usatoday.com/">USAtoday.com </a>, a leading online news agency in the USA, stands out. Our dedication to delivering the most current news about the USA and the world makes us a go-to resource for readers who seek to stay ahead of the curve.

    Subscribe for Exclusive Content: By subscribing to <a href="https://www.usatoday.com/">USAtoday.com</a>, you gain access to exclusive content, newsletters, and updates that keep you ahead of the news cycle.

    <a href="https://www.usatoday.com/">USAtoday.com </a> is not just a news website; it's a dynamic platform that empowers its readers through timely, accurate, and comprehensive reporting. As we navigate through an ever-changing landscape, our mission remains unwavering: to keep you informed, engaged, and connected. Subscribe to us today and become part of a community that values quality journalism and informed citizenship.