Ich habe mit der Google Analytics-API (V3) herumgespielt und bin auf einige Fehler gestoßen. Erstens ist alles korrekt eingerichtet und funktioniert mit meinem Testkonto. Wenn ich jedoch Daten von einer anderen Profil-ID (gleiches Google Accont / GA-Konto) abrufen möchte, wird ein 403-Fehler angezeigt. Das Seltsame ist, dass Daten von einigen GA-Konten Daten zurückgeben, während andere diesen Fehler erzeugen.
Ich habe das Token widerrufen und noch einmal authentifiziert, und jetzt kann ich anscheinend Daten von allen meinen Konten abrufen. Problem gelöst? Nicht. Da der Zugriffsschlüssel abläuft, werde ich erneut auf dasselbe Problem stoßen.
Wenn ich die Dinge richtig verstanden habe, könnte man das resfreshToken verwenden, um eine neue Authentifizierung zu erhalten.
Das Problem ist, wenn ich laufe:
$client->refreshToken(refresh_token_key)
Der folgende Fehler wird zurückgegeben:
Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'
Ich habe den Code hinter der refreshToken-Methode überprüft und die Anforderung bis zur Datei "apiOAuth2.php" zurückverfolgt. Alle Parameter werden korrekt gesendet. Der grant_type ist innerhalb der Methode fest in 'refresh_token' codiert, daher fällt es mir schwer zu verstehen, was falsch ist. Das Parameterarray sieht folgendermaßen aus:
Array ( [client_id] => *******-uqgau8uo1l96bd09eurdub26c9ftr2io.apps.googleusercontent.com [client_secret] => ******** [refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY [grant_type] => refresh_token )
Das Verfahren ist wie folgt.
$client = new apiClient();
$client->setClientId($config['oauth2_client_id']);
$client->setClientSecret($config['oauth2_client_secret']);
$client->setRedirectUri($config['oauth2_redirect_uri']);
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');
$client->setState('offline');
$client->setAccessToken($config['token']); // The access JSON object.
$client->refreshToken($config['refreshToken']); // Will return error here
Ist das ein Fehler oder habe ich etwas völlig falsch verstanden?
quelle
Antworten:
Also habe ich endlich herausgefunden, wie das geht. Die Grundidee ist, dass Sie das Token haben, das Sie erhalten, wenn Sie zum ersten Mal nach Authentifizierung fragen. Dieses erste Token verfügt über ein Aktualisierungstoken. Der erste Original-Token läuft nach einer Stunde ab. Nach einer Stunde müssen Sie das Aktualisierungstoken vom ersten Token verwenden, um ein neues verwendbares Token zu erhalten. Sie verwenden
$client->refreshToken($refreshToken)
, um ein neues Token abzurufen. Ich werde dies "temporäres Token" nennen. Sie müssen dieses temporäre Token ebenfalls speichern, da es nach einer Stunde ebenfalls abläuft und kein Aktualisierungstoken zugeordnet ist. Um ein neues temporäres Token zu erhalten, müssen Sie die zuvor verwendete Methode verwenden und das Refreshtoken des ersten Tokens verwenden. Ich habe unten Code angehängt, was hässlich ist, aber ich bin neu in diesem ...quelle
$client->isAccessTokenExpired()
weiterhin nur die lokal gehaltenen Zeiten überprüft werden, um festzustellen, ob das Token abgelaufen ist. Das Token ist möglicherweise noch abgelaufen und die lokale Anwendung weiß erst wirklich, wann sie versucht, es zu verwenden. In diesem Fall gibt der API-Client eine Ausnahme zurück und aktualisiert das Token nicht automatisch.Das Problem liegt im Aktualisierungstoken:
Wenn ein String mit einem
'/'
get wirdjson encoded
, wird er mit einem'\'
maskiert, daher müssen Sie ihn entfernen.Das Aktualisierungstoken in Ihrem Fall sollte sein:
Ich gehe davon aus, dass Sie die JSON-Zeichenfolge gedruckt haben, die Google zurückgesendet und das Token kopiert und in Ihren Code eingefügt hat, denn wenn Sie
json_decode
es tun, wird es das'\'
für Sie korrekt entfernen !quelle
Hier ist das Snippet zum Festlegen des Tokens. Stellen Sie zuvor sicher, dass der Zugriffstyp auf Offline gesetzt ist
Token aktualisieren
Dadurch wird Ihr Token aktualisiert. Sie müssen es in der Sitzung aktualisieren, damit Sie dies tun können
quelle
Der Zugriffstyp sollte auf eingestellt sein
offline
.state
ist eine Variable, die Sie für Ihren eigenen Gebrauch festlegen, nicht für die Verwendung durch die API.Stellen Sie sicher, dass Sie über die neueste Version der Clientbibliothek verfügen, und fügen Sie Folgendes hinzu:
Eine Erläuterung der Parameter finden Sie unter Erstellen der URL .
quelle
$client
($client = new apiClient();
) einrichten müssen , um das Aktualisierungstoken zu verwenden?$client->setApprovalPrompt('force')
sowie$client->setAccessType('offline')
ein neues Aktualisierungstoken während der Autorisierung erhalten. Ohne den Nutzer zu zwingen, den Zugriffsbereich zu genehmigen, geht Google davon aus, dass Sie das alte Aktualisierungstoken weiterhin verwenden werden.Die Antwort von @ uri-weg hat bei mir funktioniert, aber da ich seine Erklärungen nicht sehr klar fand, möchte ich sie ein wenig umformulieren.
Wenn Sie während der ersten Zugriffsberechtigungssequenz im Rückruf den Punkt erreichen, an dem Sie einen Authentifizierungscode erhalten, müssen Sie auch das Zugriffstoken und das Aktualisierungstoken speichern .
Der Grund dafür ist, dass Google API Ihnen nur dann ein Zugriffstoken mit einem Aktualisierungstoken sendet, wenn Sie zur Eingabe der Zugriffsberechtigung aufgefordert werden. Die nächsten Zugriffstoken werden ohne Aktualisierungstoken gesendet (es sei denn, Sie verwenden die
approval_prompt=force
Option).Das Aktualisierungstoken, das Sie zum ersten Mal erhalten haben, bleibt gültig, bis der Benutzer die Zugriffsberechtigung widerruft.
In vereinfachter PHP wäre ein Beispiel für die Rückrufsequenz:
Und später, in vereinfachtem PHP, wäre die Verbindungssequenz:
quelle
// setAccessToken() expects json
das ausreichend. Oder ist es für einen anderen Teil des Codes?Hier ist der Code, den ich in meinem Projekt verwende und der gut funktioniert:
quelle
Hatte das gleiche Problem; Mein Skript, das gestern aus irgendeinem Grund funktioniert hat, hat heute nicht funktioniert. Keine Änderungen.
Anscheinend lag dies daran, dass meine Systemuhr um 2,5 (!!) Sekunden ausgeschaltet war und durch die Synchronisierung mit NTP behoben wurde.
Siehe auch: https://code.google.com/p/google-api-php-client/wiki/OAuth2#Solving_invalid_grant_errors
quelle
sudo apt-get install ntp
auf meinem Debian-Computer ausgeführt, um NTP zu installieren. Es synchronisierte die Uhr und das Problem wurde gelöst.Zu Ihrer Information: Die Google Analytics-API 3.0 aktualisiert das Zugriffstoken automatisch, wenn Sie ein Aktualisierungstoken haben, wenn es abläuft, sodass Ihr Skript es nie benötigt
refreshToken
.(Siehe die
Sign
Funktion inauth/apiOAuth2.php
)quelle
Manchmal wird ein Aktualisierungstoken nicht mithilfe von generiert
$client->setAccessType ("offline");
.Versuche dies:
quelle
Ich habe das Beispiel von Smartcodes mit der aktuellen Version der Google-API verwendet, aber diese hat nicht funktioniert. Ich denke, seine API ist zu veraltet.
Also habe ich gerade meine eigene Version geschrieben, basierend auf einem der API-Beispiele ... Sie gibt Zugriffstoken, Anforderungstoken, Tokentyp, ID-Token, Ablaufzeit und Erstellungszeit als Zeichenfolgen aus
Wenn Ihre Client-Anmeldeinformationen und Ihr Entwicklerschlüssel korrekt sind, sollte dieser Code sofort funktionieren.
quelle
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
. Warum leiten Sie zur gleichen Seite weiter? ist das notwendig?Ich habe das gleiche Problem mit Google / Google-API-PHP-Client v2.0.0-RC7 und nach 1-stündiger Suche habe ich dieses Problem mit json_encode wie folgt gelöst :
quelle
Das hier funktioniert sehr gut, vielleicht könnte es jedem helfen:
index.php
oauth2callback.php
client.php
action.php
quelle
Google hat einige Änderungen vorgenommen, seit diese Frage ursprünglich veröffentlicht wurde.
Hier ist mein aktuelles Arbeitsbeispiel.
quelle
Ich verwende google-api-php-client v2.2.2 Ich erhalte ein neues Token mit einem
fetchAccessTokenWithRefreshToken();
Funktionsaufruf ohne Parameter, der ein aktualisiertes Zugriffstoken zurückgibt und das aktualisierte Token nicht verloren geht.quelle
Sie müssen das Zugriffstoken während der Erstautorisierungsanforderung als JSON-Zeichenfolge in einer Datei oder Datenbank speichern und den Zugriffstyp auf Offline setzen
$client->setAccessType("offline")
Nehmen Sie dann bei nachfolgenden API-Anforderungen das Zugriffstoken aus Ihrer Datei oder Datenbank und übergeben Sie es an den Client:
Jetzt müssen Sie überprüfen, ob das Token abgelaufen ist:
Die
fetchAccessTokenWithRefreshToken()
Funktion erledigt die Arbeit für Sie und stellt ein neues Zugriffstoken bereit. Speichern Sie es zurück in Ihrer Datei oder Datenbank.quelle
Gemäß Authentifizierung bei Google: OAuth2 gibt immer wieder "invalid_grant" zurück.
"Sie sollten das Zugriffstoken, das Sie nach der ersten erfolgreichen Authentifizierung erhalten, wiederverwenden. Wenn Ihr vorheriges Token noch nicht abgelaufen ist, wird der Fehler invalid_grant angezeigt. Speichern Sie es irgendwo, damit Sie es wiederverwenden können."
ich hoffe es hilft
quelle
Verwenden Sie das folgende Codefragment, um Ihr Aktualisierungstoken abzurufen
quelle