Holen Sie sich Aktualisierungstoken Google API

76

Ich kann mein Aktualisierungstoken nicht mit meinem Code erhalten. Ich kann nur mein Zugriffstoken, meinen Tokentyp usw. erhalten. Ich habe einige Tutorials wie das Anlegen access_type=offlinemeiner Anmelde-URL befolgt :

echo "<a href='https://accounts.google.com/o/oauth2/auth?" 
    . "access_type=offline&client_id=123345555.apps.googleusercontent.com& "
    . "scope=https://www.googleapis.com/auth/calendar+https://www.googleapis.com/auth/plus.me&response_type=code& "
    . "redirect_uri=http://www.sample.com/sample.php&state=/profile'>Google</a>";

und meine Felder beim Abrufen des Zugriffstokens:

$fields=array(
    'code'=>  urlencode($authcode),
    'client_id'=> urlencode($clientid),
    'client_secret'=> urlencode($clientsecret),
    'redirect_uri'=> urlencode($redirecturi),
    'grant_type'=> 'authorization_code',
);

Ich kann jedoch kein refresh_token erhalten , nur das access_token , den token_type , das id_token und das expires_in .

Robin Carlo Katakutan
quelle
1
/ * Überprüfen Sie diesen Link, der für mich funktioniert @
Manmeet Khurana

Antworten:

107

Finden Sie es heraus, indem Sie dies zu Ihren URL-Parametern hinzufügen

Approval_prompt = Kraft

Aktualisieren:

Verwenden Sie access_type=offline&prompt=consentstattdessen.

approval_prompt=forcefunktioniert nicht mehr https://github.com/googleapis/oauth2client/issues/453

Robin Carlo Katakutan
quelle
12
Warum funktioniert es nicht mit Auto? Ich möchte nicht, dass Benutzer jedes Mal die Erlaubnis erteilen. Wie kann ich das überwinden?
Harsha MV
6
Weil das Reresh-Token erst beim ersten Erteilen der Anwendungsberechtigung zurückgegeben wird. Danach haben alle Anfragen mit approval_prompt=autokein refresh_token mehr. Überprüfen Sie diese Antwort für eine detailliertere Erklärung stackoverflow.com/a/10857806/987864
Daan
4
Sie benötigen access_type=offlinein allen Fällen, wenn Sie das refresh_token
Daan
7
Die bearbeitete Antwort auf etwas, das funktioniert, da diese Antwort alt ist und nicht mehr zu funktionieren scheint. Ich habe viel Zeit damit verbracht, dies zu versuchen, da es mehrere Stellen gibt, die sagen, dass diese Methode angewendet werden soll. Ich habe endlich die Dokumentation gelesen (was ich zuerst hätte tun sollen) und sie besagt, dass Sie sie verwenden müssen prompt=consent. Referenz: developer.google.com/identity/protocols/…
Goblinlord
8
Sowohl @Daan als auch @Goblinlord sind korrekt, ich hatte auch nach dem Lesen ihrer Kommentare damit zu kämpfen. Tatsächlich brauchen wir BEIDE access_type=offline&prompt=consent. Andernfalls ist das refresh_tokennicht vorhanden.
Noitidart
62

Wenn ich die Antwort von user987361 erweitern darf :

Aus dem Offline-Zugriffsteil der OAuth2.0-Dokumente:

Wenn Ihre Anwendung ein Aktualisierungstoken erhält, ist es wichtig, dieses Aktualisierungstoken für die zukünftige Verwendung zu speichern. Wenn Ihre Anwendung das Aktualisierungstoken verliert, muss sie den Benutzer erneut zur Zustimmung auffordern, bevor sie ein weiteres Aktualisierungstoken erhält. Wenn Sie den Benutzer erneut zur Einwilligung auffordern müssen, fügen Sie den approval_prompt Parameter in die Autorisierungscode-Anforderung ein und setzen Sie den Wert auf force.

Also, wenn Sie bereits Zugriff gewährt haben, nachfolgende Anforderungen für ein grant_typevon authorization_codewerden die nicht zurückkehren refresh_token, auch wenn access_typegesetzt wurde offlinedie Zustimmung Seite in dem Query - String.

Wie in dem Zitat oben erwähnt, um eine zu erhalten , neu refresh_token , nachdem bereits die Aufnahme eines, müssen Sie Ihren Benutzer zurück durch die Aufforderung senden, die Sie , indem Sie tun können , approval_promptzu force.

Prost,

PS Diese Änderung wurde auch in einem Blogbeitrag angekündigt .

Bossylobster
quelle
3
Ich würde hinzufügen, dass Sie nur dann ein neues benötigen, refresh tokenwenn Sie es verlieren oder Ihr Benutzer Ihren Zugriff widerruft. Andernfalls können Sie dasselbe weiterhin verwenden refresh token, um neue access tokens zu erhalten .
Jeteon
1
Ich habe ein CMS, in dem verschiedene Benutzer unterschiedliche Google-Konten verwenden, um eine Verbindung zur Analytics-API herzustellen. Manchmal können jedoch mehrere Benutzer eine Verbindung mit demselben Google-Unternehmenskonto herstellen, die jedoch jeweils Zugriff auf ein anderes Analytics-Konto wünschen. Nur der erste erhält das Aktualisierungstoken, während alle anderen dies nicht tun und daher jede Stunde eine neue Verbindung herstellen müssen. Gibt es nicht eine Möglichkeit, das gleiche Aktualisierungstoken für nachfolgende Authentifizierungen zu erhalten, anstatt nur das access_token, das innerhalb einer Stunde abläuft?
SsjCosty
Ja. TU es einfach. Wenn Sie die Anfrage senden, erhalten Sie ein Zugriffstoken und das Aktualisierungstoken zurück.
Bossylobster
Ich hatte Mühe, ein refresh_token zu bekommen, und Sie haben mich mit der Lösung aufgeklärt !!! "Wenn Sie also bereits Zugriff gewährt haben, geben nachfolgende Anforderungen für einen Grant-Typ des Autorisierungscodes das refresh_token nicht zurück, selbst wenn access_type in der Abfragezeichenfolge der Einwilligungsseite auf offline gesetzt wurde."
Cristiana S. Parada
12

Es ist access_type=offlinedas du willst.

Dadurch wird das Aktualisierungstoken zurückgegeben, wenn der Benutzer die App zum ersten Mal autorisiert. Nachfolgende Aufrufe zwingen Sie nicht, die App erneut zu genehmigen ( approval_prompt=force).

Weitere Informationen finden Sie unter: https://developers.google.com/accounts/docs/OAuth2WebServer#offline

Elliot Coad
quelle
1
Diese verknüpfte Seite gibt an, dass der Google-Client sich um die Erneuerung des Zugriffstokens kümmert, wenn es abläuft (das Erneuerungstoken befindet sich vermutlich in der geheimen XML-Datei), zeigt jedoch nicht an, wie Sie feststellen würden, dass sich das Zugriffstoken geändert hat, damit dies möglich ist in der Anwendung für den nächsten Zugriff gespeichert werden. Gibt es dafür einen Rückruf oder sollte eine Anwendung immer prüfen, ob sich das Zugriffstoken bei jedem Remotezugriff geändert hat ?
Jason
10

Dies ist vollständiger Code in PHP mit dem offiziellen Google SDK

$client = new Google_Client();
## some need parameter
$client->setApplicationName('your application name');
$client->setClientId('****************');
$client->setClientSecret('************');
$client->setRedirectUri('http://your.website.tld/complete/url2redirect');
$client->setScopes('https://www.googleapis.com/auth/userinfo.email');
## these two lines is important to get refresh token from google api
$client->setAccessType('offline');
$client->setApprovalPrompt('force'); # this line is important when you revoke permission from your app, it will prompt google approval dialogue box forcefully to user to grant offline access
Shahadat Hossain Khan
quelle
8

Für unsere App mussten wir beide Parameter verwenden access_type=offline&prompt=consent. approval_prompt=force hat bei uns nicht funktioniert

Ricky
quelle
1
Danke Ricky, das hat mir auch geholfen. Ich denke, die älteren Antworten, die darauf hindeuten approval_prompt=force, waren zu dieser Zeit wahrscheinlich richtig, funktionieren aber nicht mehr. Es gibt einige Diskussionen hier: github.com/google/oauth2client/issues/453
Mike Morearty
7

Hallo, ich habe die folgenden Schritte ausgeführt und konnte das Aktualisierungstoken erhalten.

Der Autorisierungsablauf besteht aus zwei Schritten.

  1. Ist es, den Autorisierungscode über die https://accounts.google.com/o/oauth2/auth?URL zu erhalten.

    Dazu wird eine Post-Anfrage mit folgenden Parametern gesendet. 'scope=' + SCOPE + '&client_id=' + CLIENTID + '&redirect_uri=' + REDIRECT + '&response_type=' + TYPE + '&access_type=offline'Wenn Sie oben angeben, erhalten Sie einen Autorisierungscode.

  2. Abrufen von AcessToken und RefreshToken mithilfe der https://accounts.google.com/o/oauth2/token?URL. Dazu wird eine Post-Anfrage mit folgenden Parametern gesendet.

    "code": code, "client_id": CID, "client_secret": CSECRET, "redirect_uri": REDIRECT, "grant_type": "authorisation_code",

Wenn Sie also beim ersten Versuch die Berechtigungen autorisieren, können Sie das Aktualisierungstoken erhalten. Nachfolgende Versuche liefern das Aktualisierungstoken nicht. Wenn Sie das Token erneut möchten, widerrufen Sie den Zugriff in Ihrer Anwendung.

Hoffe das wird jemandem helfen jubeln :)

dnWick
quelle
4

OAuth hat zwei Szenarien im Real-Modus. Der normale und standardmäßige Zugriffsstil wird als Online bezeichnet. In einigen Fällen muss Ihre Anwendung möglicherweise auf eine Google-API zugreifen, wenn der Nutzer nicht anwesend ist. , Es handelt sich um Offline-Szenarien. In Offline-Szenarien wird beim ersten Austausch des Autorisierungscodes ein Aktualisierungstoken abgerufen.

Sie können also referesh_token erhalten, einige Szenarien, nicht alle.

Sie können den Inhalt unter https://developers.google.com/identity/protocols/OAuth2WebServer#offline haben .

Julian89757
quelle
0

Für diejenigen, die die Google API Client Library für PHP verwenden und Offline-Zugriff und Aktualisierungstoken suchen, ist zum Zeitpunkt des Schreibens zu beachten, dass in den Dokumenten falsche Beispiele angezeigt werden.

Derzeit wird Folgendes angezeigt:

$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');
// Using "consent" ensures that your application always receives a refresh token.
// If you are not using offline access, you can omit this.
$client->setApprovalPrompt("consent");
$client->setIncludeGrantedScopes(true);   // incremental auth

Quelle: https://developers.google.com/identity/protocols/OAuth2WebServer#offline

All dies funktioniert großartig - bis auf EIN Stück

$client->setApprovalPrompt("consent");

Nach einigem Überlegen habe ich diese Zeile in die folgende geändert und ALLES hat funktioniert

$client->setPrompt("consent");

Dies ist sinnvoll, da die Verwendung der HTTP-Anforderungen von Approval_prompt = Force in Prompt = Einwilligung geändert wurde . Das Ändern der Setter-Methode von setApprovalPrompt auf setPrompt folgt also der natürlichen Konvention - ABER ES IST NICHT IN DEN DOCS !!! Das habe ich zumindest gefunden.

Jay
quelle