412 Stimmen

Google OAuth Refresh-Token nicht erhalten

Ich möchte das Zugriffstoken von Google erhalten. Die Google API sagt dass Sie, um das Zugriffs-Token zu erhalten, den Code und andere Parameter an die Token-Generierungsseite senden, und die Antwort wird ein JSON-Objekt sein wie :

{
"access_token" : "ya29.AHES6ZTtm7SuokEB-RGtbBty9IIlNiP9-eNMMQKtXdMP3sfjL1Fc",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/HKSmLFXzqP0leUihZp2xUt3-5wkU7Gmu2Os_eBnzw74"
}

Ich erhalte jedoch das Aktualisierungs-Token nicht. Die Antwort lautet in meinem Fall:

{
 "access_token" : "ya29.sddsdsdsdsds_h9v_nF0IR7XcwDK8XFB2EbvtxmgvB-4oZ8oU",
"token_type" : "Bearer",
"expires_in" : 3600
}

9voto

Zack Morris Punkte 4504

Die Antwort von Rich Sutton hat bei mir endlich funktioniert, nachdem ich festgestellt hatte, dass das Hinzufügen von access_type=offline erfolgt auf der vorderes Ende die Anfrage des Kunden nach einem Autorisierungscode, no die Backend-Anfrage, die diesen Code gegen ein access_token austauscht. Ich habe einen Kommentar zu seiner Antwort hinzugefügt und dieser Link bei Google für weitere Informationen zum Aktualisieren von Token.

P.S.: Wenn Sie Satellizer verwenden, So fügen Sie diese Option in der Datei $authProvider.google in AngularJS hinzu .

7voto

coreyward Punkte 72986

Um die refresh_token müssen Sie folgende Angaben machen access_type=offline in der URL der OAuth-Anfrage. Wenn sich ein Benutzer zum ersten Mal authentifiziert, erhalten Sie einen Wert zurück, der nicht null ist refresh_token sowie eine access_token die abläuft.

Wenn Sie eine Situation haben, in der ein Nutzer ein Konto, für das Sie bereits ein Authentifizierungs-Token haben, erneut authentifizieren könnte (wie @SsjCosty oben erwähnt), müssen Sie von Google Informationen darüber zurückerhalten, für welches Konto das Token ist. Fügen Sie dazu Folgendes hinzu profile zu Ihren Bereichen. Mit dem OAuth2 Ruby-Gem könnte Ihre endgültige Anfrage etwa so aussehen:

client = OAuth2::Client.new(
  ENV["GOOGLE_CLIENT_ID"],
  ENV["GOOGLE_CLIENT_SECRET"],
  authorize_url: "https://accounts.google.com/o/oauth2/auth",
  token_url: "https://accounts.google.com/o/oauth2/token"
)

# Configure authorization url
client.authorize_url(
  scope: "https://www.googleapis.com/auth/analytics.readonly profile",
  redirect_uri: callback_url,
  access_type: "offline",
  prompt: "select_account"
)

Beachten Sie, dass der Bereich zwei durch Leerzeichen getrennte Einträge hat, einen für den Nur-Lese-Zugriff auf Google Analytics, und der andere ist nur profile der ein OpenID Connect-Standard ist.

Dies wird dazu führen, dass Google ein zusätzliches Attribut namens id_token im get_token Antwort. Um Informationen aus dem id_token zu erhalten, siehe diese Seite in den Google-Dokumenten. Es gibt eine Handvoll von Google bereitgestellter Bibliotheken, die dies für Sie validieren und "dekodieren" können (ich habe die Ruby google-id-token gem ). Sobald Sie es geparst haben, wird die sub ist praktisch die eindeutige Google-Konto-ID.

Erwähnenswert ist, wenn Sie ändern den Bereich, erhalten Sie erneut ein Refresh-Token für Benutzer, die sich bereits mit dem ursprünglichen Bereich authentifiziert haben. Dies ist nützlich, wenn Sie z. B. bereits eine Reihe von Nutzern haben und nicht wollen, dass sie alle die Authentifizierung der App in Google aufheben.

Oh, und noch ein letzter Hinweis: Sie müssen nicht brauchen prompt=select_account Es ist jedoch nützlich, wenn Sie eine Situation haben, in der sich Ihre Nutzer mit mehr als einem Google-Konto authentifizieren möchten (d. h. Sie verwenden dies nicht für die Anmeldung/Authentifizierung).

3voto

Mazahir Haroon Punkte 31

1. Wie erhält man 'refresh_token'?

Lösung: access_type='offline' sollte bei der Erstellung der authURL verwendet werden. Quelle: Verwendung von OAuth 2.0 für Webserver-Anwendungen

2. Aber selbst mit "access_type=offline" erhalte ich das "refresh_token" nicht?

Lösung: Bitte beachten Sie, dass Sie diesen Wert nur bei der ersten Anfrage erhalten. Wenn Sie ihn also irgendwo speichern und es in Ihrem Code vorgesehen ist, diesen Wert zu überschreiben, wenn Sie einen neuen access_token erhalten, nachdem der vorherige abgelaufen ist, dann stellen Sie sicher, dass Sie diesen Wert nicht überschreiben.

Aus Google Auth Doc : (dieser Wert = access_type)

Dieser Wert weist den Google-Autorisierungsserver an Refresh-Token und ein Access-Token zurückzugeben. einen Autorisierungscode gegen Token austauscht.

Wenn Sie "refresh_token" erneut benötigen, müssen Sie den Zugriff für Ihre Anwendung entfernen, indem Sie die Schritte in Die Antwort von Rich Sutton .

3voto

jarraga Punkte 176

Ich verwende einen Nodejs-Client für den Zugriff auf private Daten

Die Lösung war das Hinzufügen der prompte Eigenschaft mit Wert Zustimmung zum Einstellungsobjekt in oAuth2Client.generateAuthUrl Funktion. Hier ist mein Code:

const getNewToken = (oAuth2Client, callback) => {
    const authUrl = oAuth2Client.generateAuthUrl({
        access_type: 'offline',
        prompt: 'consent',
        scope: SCOPES,
    })
    console.log('Authorize this app by visiting this url:', authUrl)
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
    })
    rl.question('Enter the code from that page here: ', (code) => {
        rl.close()
        oAuth2Client.getToken(code, (err, token) => {
            if (err) return console.error('Error while trying to retrieve access token', err)
            oAuth2Client.setCredentials(token)
            // Store the token to disk for later program executions
            fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
                if (err) return console.error(err)
                console.log('Token stored to', TOKEN_PATH)
            })
            callback(oAuth2Client)
        })
    })
}

Sie können den Online-Parameter-Extraktor verwenden, um den Code für die Erstellung Ihres Tokens zu erhalten:

Online-Parameter-Extraktor

Hier ist der vollständige Code aus den offiziellen Google-Dokumenten:

https://developers.google.com/sheets/api/quickstart/nodejs

Ich hoffe, die Informationen sind nützlich

2voto

apadana Punkte 11390

Diese Einstellung bewirkt, dass das Aktualisierungs-Token jedes Mal gesendet wird:

$client->setApprovalPrompt('force');

Ein Beispiel ist unten angegeben (php):

$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("email");
$client->addScope("profile"); 
$client->setAccessType('offline');
$client->setApprovalPrompt('force');

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X