wake-up-neo.com

invalid_grant versucht, oAuth-Token von Google zu erhalten

Beim Versuch, ein oAuth-Token von Google zu erhalten, wird eine invalid_grant-Fehlermeldung angezeigt, um eine Verbindung zu ihren Kontakt-APIs herzustellen. Alle Informationen sind korrekt und ich habe das alles so verdammt überprüft.

Weiß jemand, was dieses Problem verursachen kann? Ich habe versucht, eine andere Client-ID einzurichten, aber ich erhalte das gleiche Ergebnis. Ich habe versucht, viele verschiedene Arten der Verbindung herzustellen, einschließlich der Zwangsauthentifizierung, aber das gleiche Ergebnis.

91
André Figueira

Ich bin auf dieses Problem gestoßen, als ich nicht explizit nach "offline" -Zugang gefragt habe, als ich den Benutzer an OAuth sandte. "Möchten Sie dieser App die Berechtigung geben, Ihre Sachen zu berühren?" Seite.

Stellen Sie sicher, dass Sie in Ihrer Anforderung access_type = offline angeben.

Details hier: https://developers.google.com/accounts/docs/OAuth2WebServer#offline

(Außerdem: Ich denke, Google hat diese Einschränkung Ende 2011 hinzugefügt. Wenn Sie über alte Token von früher verfügen, müssen Sie Ihre Benutzer zur Berechtigungsseite senden, um die Offline-Verwendung zuzulassen.)

51
bonkydog

Ich bin auf dasselbe Problem gestoßen, obwohl ich den "Offline" access_type in meiner Anfrage als Bonkydogs Antwort angegeben habe. Um es kurz zu machen: Ich habe festgestellt, dass die hier beschriebene Lösung für mich funktioniert hat:

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

Wenn Sie einen OAuth2-Client in Ihre Google API-Konsole einfügen, erhalten Sie im Wesentlichen eine "Client-ID" und eine "E-Mail-Adresse" (vorausgesetzt, Sie wählen "webapp" als Ihren Kundentyp aus). Und trotz der irreführenden Namenskonventionen von Google erwarten Sie, dass Sie beim Zugriff auf die OAuth2-APIs die "E-Mail-Adresse" als Wert des Parameters client_id senden. 

Dies gilt beim Aufruf dieser beiden URLs:

Beachten Sie, dass der Aufruf der ersten URL success ist, wenn Sie ihn mit Ihrer "Client-ID" anstelle Ihrer "E-Mail-Adresse" aufrufen. Die Verwendung des von dieser Anforderung zurückgegebenen Codes funktioniert jedoch nicht, wenn versucht wird, ein Trägertoken von der zweiten URL abzurufen. Stattdessen erhalten Sie eine "Fehler 400" und eine "invalid_grant" -Meldung. 

55
aroth

Obwohl dies eine alte Frage ist, scheint es, als würden viele immer noch darauf stoßen - wir haben tagelang damit verbracht, dies selbst zu finden.

In der OAuth2-Spezifikation ist "invalid_grant" eine Art Alleskönner für alle Fehler im Zusammenhang mit ungültigen/abgelaufenen/aufgehobenen Token (Auth Grant oder Refresh-Token).

Für uns war das Problem zweierlei: 

  1. Benutzer hat den Zugriff auf unsere App aktiv widerrufen
    Ist sinnvoll, aber erhalten Sie Folgendes: 12 Stunden nach dem Widerruf, Google stoppt das Senden die Fehlermeldung in ihrer Antwort: “error_description” : “Token has been revoked.”
    Es ist ziemlich irreführend, da Sie davon ausgehen, dass die Fehlernachricht immer vorhanden ist, was nicht der Fall ist. Sie können auf der Berechtigungsseite apps nachsehen, ob Ihre App noch Zugriff hat .

  2. Benutzer hat sein Google-Passwort zurückgesetzt/wiederhergestellt
    Im Dezember 2015 wurde Google geändert sein Standardverhalten, sodass das Zurücksetzen von Kennwörtern für Nutzer, die keine Google Apps-Apps sind, automatisch alle Aktualisierungstoken der Apps für Nutzer widerruft. Beim Widerruf folgt die Fehlermeldung der gleichen Regel wie im vorherigen Fall, sodass Sie in den ersten 12 Stunden nur die "error_description" erhalten. Es scheint keine Möglichkeit zu geben, zu wissen, ob der Benutzer den Zugriff manuell widerrufen hat (absichtlich), oder dass dies aufgrund eines Zurücksetzens des Kennworts (Nebeneffekt) geschah.

Abgesehen von diesen gibt es eine Vielzahl anderer potenzieller Ursachen, die den Fehler auslösen könnten:

  1. Serveruhrzeit/Zeit ist nicht synchron
  2. Nicht für den Offlinezugriff berechtigt
  3. Throttled von Google
  4. Verwenden abgelaufener Aktualisierungsmarker
  5. Benutzer war seit 6 Monaten inaktiv
  6. Service-Worker-E-Mail anstelle von Client-ID verwenden
  7. Zu viele Zugriffstoken in kurzer Zeit
  8. Client-SDK ist möglicherweise veraltet
  9. Falsches/unvollständiges Aktualisierungstoken

Ich habe einen kurzen Artikel geschrieben Ich fasse jeden Punkt mit einigen Debugging-Anleitungen zusammen, um den Schuldigen zu finden. Ich hoffe es hilft.

41
laander

Ich bin auf das gleiche Problem gestoßen. Für mich habe ich dies behoben, indem ich E-Mail-Adresse (die Zeichenfolge, die mit ... @ developer.gserviceaccount.com endet) anstelle der Client-ID für den Parameterwert client_id verwendet. Die von Google festgelegte Benennung ist hier verwirrend.

7
Tony Vu

Mein Problem war, dass ich diese URL verwendet habe:

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

Wann hätte ich diese URL verwenden sollen:

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

Hierbei wurde ein Dienstkonto getestet, das einen Offline-Zugriff auf die Storage Engine wollte.

2
Brad Lee

Ich hatte die gleiche Fehlermeldung 'invalid_grant' und es lag daran, dass das authResult ['code'] Send von clientseitigem Javascript nicht korrekt auf dem Server empfangen wurde. 

Versuchen Sie, es vom Server zurück auszugeben, um zu sehen, ob es korrekt ist und keine leere Zeichenfolge.

2
Mihai Crăiță

Möglicherweise müssen Sie eine veraltete/ungültige OAuth-Antwort entfernen. 

Kredit: node.js google oauth2-Beispiel funktioniert nicht mehr invalid_grant

Note: Eine OAuth-Antwort wird auch ungültig, wenn das in der ursprünglichen Autorisierung verwendete Kennwort geändert wurde.

Wenn Sie sich in einer Bash-Umgebung befinden, können Sie die veraltete Antwort folgendermaßen entfernen:

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

1
Lindauson

Es gibt zwei Hauptgründe für den invalid_grant - Fehler, den Sie vor der POST - Anforderung für Refresh Token und Access Token beachten müssen.

  1. Der Anforderungsheader muss "content-type: application/x-www-form-urlencoded" enthalten.
  2. Ihre Anforderungsnutzdaten sollten url-codierte Formulardaten sein, nicht als Json-Objekt senden.

RFC 6749 OAuth 2.0 definierte invalid_grant als: Die bereitgestellte Berechtigungsgewährung (z. B. Autorisierungscode, Berechtigungsnachweise des Ressourcenbesitzers) oder Aktualisierungstoken ist ungültig, abgelaufen, widerrufen und stimmt nicht mit dem überein Umleitungs-URI, der in der Autorisierungsanforderung verwendet wurde oder an einen anderen Client ausgegeben wurde.

Ich habe einen anderen guten Artikel gefunden, hier Sie werden viele andere Gründe für diesen Fehler finden.

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

1
Hisham Javed

Dies ist eine dumme Antwort, aber das Problem für mich war, dass ich nicht erkannte, dass ich bereits einen aktiven oAuth-Token für meinen Google-Benutzer ausgestellt hatte, den ich nicht speichern konnte. Die Lösung in diesem Fall ist, zur api-Konsole zu gehen und das Clientgeheimnis zurückzusetzen.

Zu diesem Zweck gibt es zahlreiche andere Antworten auf SO Reset Client Secret OAuth2 - Müssen Clients den Zugriff erneut gewähren?

1
paul

wenn Sie die Scribe-Bibliothek verwenden, richten Sie einfach den Offline-Modus ein, wie von bonkydog vorgeschlagen Hier ist der Code: 

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

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

1

Bei Verwendung einer Android-Client-ID (kein client_secret) erhielt ich die folgende Fehlerantwort:

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

Ich kann keine Dokumentation für das Feld 'code_verifier' finden. Ich habe jedoch festgestellt, dass bei der Autorisierung und bei Token-Anforderungen gleiche Werte festgelegt werden. Der Fehler wird dadurch entfernt. Ich bin nicht sicher, was der beabsichtigte Wert sein sollte oder ob er sicher sein sollte. Es hat eine minimale Länge (16 Zeichen), aber ich fand, dass die Einstellung auf null auch funktioniert.

Ich verwende AppAuth für die Autorisierungsanfrage in meinem Android-Client, der eine setCodeVerifier()-Funktion hat.

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

Hier ist ein Beispiel für eine Tokenanforderung im Knoten:

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);
  }
);

Ich habe es getestet und das funktioniert sowohl mit https://www.googleapis.com/oauth2/v4/token als auch mit https://accounts.google.com/o/oauth2/token.

Wenn Sie stattdessen GoogleAuthorizationCodeTokenRequest verwenden:

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

Ändern Sie Ihre URL für die Anforderung in 

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

In meinem Fall war das Problem in meinem Code. Ich habe fälschlicherweise versucht, den Client 2 Mal mit denselben Token zu initiieren. Wenn keine der obigen Antworten hilfreich ist, stellen Sie sicher, dass Sie nicht zwei Instanzen des Clients generieren.

Mein Code vor dem Update:

def gc_service
      oauth_client = Signet::OAuth2::Client.new(client_options)
      oauth_client.code = params[:code]
      response = oauth_client.fetch_access_token!
      session[:authorization] = response
      oauth_client.update!(session[:authorization])

      gc_service = Google::Apis::CalendarV3::CalendarService.new
      gc_service.authorization = oauth_client

      gc_service
    end
primary_calendar_id = gc_service.list_calendar_lists.items.select(&:primary).first.id

gc_service.insert_acl(primary_calendar_id, acl_rule_object, send_notifications: false)

sobald ich es ändere (benutze nur eine Instanz):

@gc_service = gc_service
primary_calendar_id = @gc_service.list_calendar_lists.items.select(&:primary).first.id

@gc_service.insert_acl(primary_calendar_id, acl_rule_object, send_notifications: false)

es hat meine Probleme mit dem Grant-Typ behoben.

0
Kate Kasinskaya

auf dieser Website konsole.developers.google.com

wählen Sie Ihr Projekt aus, geben Sie die Eid-URL an . Die oauth-Callback-URL wird umgeleitet, wenn die oauth erfolgreich ist

0
user5699596

Ich hatte dieses Problem, nachdem ich eine neue Service-API in der Google-Konsole aktiviert und versucht hatte, die zuvor gemachten Anmeldeinformationen zu verwenden.

Um das Problem zu beheben, musste ich zur Anmeldeinformationsseite zurückkehren, auf den Namen der Anmeldeinformation klicken und auf "Speichern" klicken erneut. Danach konnte ich mich ganz gut authentifizieren.

0
kimphamg

Für zukünftige Leute ... Ich habe viele Artikel und Blogs gelesen, aber ich hatte Glück mit der Lösung unten ...

GoogleTokenResponse tokenResponse =
      new GoogleAuthorizationCodeTokenRequest(
          new NetHttpTransport(),
          JacksonFactory.getDefaultInstance(),
          "https://www.googleapis.com/oauth2/v4/token",
          clientId,
          clientSecret,
          authCode,
          "") //Redirect Url
     .setScopes(scopes)
     .setGrantType("authorization_code")
     .execute();

Dieses Blog zeigt verschiedene Fälle, in denen der Fehler "invalid_grant" auftritt.

Genießen!!!

0
Kanishk Gupta

Nachdem ich alle anderen Möglichkeiten in Betracht gezogen und ausprobiert habe, habe ich das Problem in nodejs mit dem Modul googleapis in Verbindung mit dem Modul request gelöst, mit dem ich anstelle der bereitgestellten getToken()-Methode die Token abrief:

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);
            }
        });

Ich verwende einfach request, um die API-Anforderung wie hier beschrieben über HTTP zu stellen: 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
0
lwdthe1

für mich musste ich sicherstellen, dass der redirect_uri genau mit dem in der Entwicklerkonsole Authorised redirect URIs übereinstimmt, der das Problem behoben hat. Ich konnte debuggen und wissen, was genau das Problem war, nachdem von https://accounts.google.com/o/oauth2/token auf https://www.googleapis.com/oauth2/v4/token gewechselt wurde.

Ich habe einen richtigen Fehler erhalten:

{"error": "redirect_uri_mismatch",  "error_description": "Bad Request"}
0
Waqleh

Für mich war das Problem, dass ich mehrere Clients in meinem Projekt hatte und ich bin mir ziemlich sicher, dass dies in Ordnung ist, aber ich habe den gesamten Client für dieses Projekt gelöscht und einen neuen erstellt und alle haben angefangen, für mich zu arbeiten Support-Forum) Ich kann diesen Link nicht als Referenz herausfinden

0
Subrata Fouzdar