2015-08-21 16 views
17

Ich verwende Google Sign-In. Ein Benutzer kommt zu meiner Site und meldet sich mit gapi.auth2.getAuthInstance().signIn() an, oder sie sind bereits eingeloggt und wenn die Seite geladen (oder neu geladen), holen wir den Status. An diesem Punkt habe ich einen Identitätsmarker, der eine Stunde lang gültig ist und den ich auf dem Server validieren kann.Wie können abgelaufene Google Log-in-Logins aktualisiert werden?

Wenn ein Benutzer den Browser verlässt (z. B. über Nacht), läuft dieses Token ab. gapi.auth2.getAuthInstance().isSignedIn.get() gibt true zurück, das Token wird jedoch nicht validiert.

Wie kann ich einen Benutzer anmelden und ihn anmelden, während seine Sitzung aktiv ist (dh der Browser wurde nicht geschlossen)? Oder aktualisieren Sie das Token? Alles, was graziöser ist, als die Seite neu zu laden ...

Edit: Das Refresh-Token ist keine richtige Antwort; Ich möchte keinen Offline-Zugriff (und möchte nicht um Erlaubnis fragen). Offensichtlich denkt Google, dass der Nutzer immer noch in meiner Anwendung angemeldet ist. Der Benutzer kann die Seite erneut laden und ein neues Token abrufen, ohne die Anmeldeinformationen erneut anzugeben. Sicherlich gibt es einen Mechanismus, der graziöser ist als ein versteckter Iframe, um ein aktualisiertes Token zu erhalten?

+1

Haben Sie eine richtige Antwort gefunden? Ich habe das gleiche Problem und weiß nicht, wie ich es lösen soll. Ich ging ursprünglich auch für Refresh Tokens, wie in der Antwort vorgeschlagen, aber ich stimme zu, dass dies keine tatsächliche Lösung ist. – csvan

+0

Noch keine Antwort, das ist verblüffend. Wenn ich etwas Freizeit habe, werde ich versuchen, eine zweite Login-Sitzung in einem versteckten iFrame zu starten und ein neues Token von dort zu ernten.In der Zwischenzeit müssen meine Benutzer ihre Seite einmal pro Stunde neu laden - yuck. – stickfigure

+1

Die Google API versucht, ihr Zugriffstoken 5 Minuten vor Ablauf zu aktualisieren. Daher sollten die meisten aktiven Sitzungen kein Problem darstellen. Das eigentliche Problem ist, was mit [setTimeout() 'geschieht, wenn der Computer schläft] (http://stackoverflow.com/a/6347336/1462337). Auf einigen (allen?) Plattformen wird die Token-Aktualisierung bis zum Zeitpunkt des Schlummerns des Computers weiter verzögert, was wahrscheinlich der letzte Zeitpunkt des aktuellen Token-Ablaufs ist. Die von @ JacekKopecký vorgeschlagene Problemumgehung - Testen auf Ablauf und Verwenden von 'reloadAuthResponse()' - funktioniert gut. Der einzige Nachteil ist, dass dies eine undokumentierte Methode ist. – rhashimoto

Antwort

0

Sie können Refresh Token verwenden, um Offline-Zugriff zu erhalten. Gemäß der offiziellen Referenz

Access tokens have limited lifetimes. If your application needs access to a Google API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.

Grundsätzlich finden Sie das refresh token Sie das erste Mal für die Authentifizierung fragen zu bekommen. Sie müssen dieses Token für die zukünftige Verwendung sicher speichern. Die access token (Sie als Identitäts-Token erwähnt) läuft nach einer Stunde ab. Danach müssen Sie die refresh token jedes Mal verwenden, wenn Sie eine neue brauchbare access token erhalten möchten.

Abhängig von der Client-Bibliothek, die Sie verwenden, wird sich die Syntax unterscheiden. Im Folgenden finden Sie ein Beispiel für eine PHP-Client-Bibliothek.

// get access token from refresh token if access token expire 

if($client->getAuth()->isAccessTokenExpired()) { 
    $client->refreshToken($securelyPreservedRefreshToken); 
    $newToken = $client->getAccessToken(); 
} 

Überprüfen Sie this für Details Schritte.

+0

Diese Antwort fehlt etwas Wesentliches. Der Benutzer kann die Seite neu laden und ein neues Token erhalten, ohne seine Anmeldeinformationen erneut eingeben zu müssen. In der Tat kann ich dieses Verhalten mit einem versteckten Iframe fast sicher verwenden, um ein neues Token zu erhalten. Daher denkt Google, dass der Nutzer immer noch auf eine sinnvolle Art und Weise bei meiner Website angemeldet ist und nicht nach einem Offline-Zugriff fragt. Ich möchte keinen Offline-Zugriff und möchte nicht um diese Erlaubnis bitten. Ich möchte nur, dass ihre Browsersitzung wie eine Facebook-Login-Sitzung fortfährt. – stickfigure

+0

Soweit ich weiß, wird die Browser-Sitzung für die Authentifizierung fortgesetzt. Wie Sie erwähnen, erhalten Sie von der auth2 'gapi.auth2.getAuthInstance(). isSignedIn.get()'. Aber Sie können erweiterte API-Anfragen nicht ohne Zugriffstoken durchführen. Daher benötigen Sie das 'refresh token', um danach' access token' zu erhalten. – arifin4web

+0

Scheint das nicht merkwürdig? Ihre API sagt "Sie sind angemeldet" und dennoch ist das Token, das es zurückgibt - um meinen Server explizit die Echtheit eines Anrufs zu bestätigen - ungültig? Ich bin eindeutig entweder angemeldet oder nicht - die Google-APIs verstehen das, und das erneute Laden der Seite stellt diese Tatsache jedes Mal eindeutig auf die eine oder andere Weise fest. Das fühlt sich an wie ein Käfer, außer dass es so offensichtlich ist, dass es schwer ist zu sehen, wie es existieren darf. – stickfigure

2

FWIW, wir haben es (meistens) geschafft, es über eine listener approach zu arbeiten. Es scheint, dass der Rückruf "userChanged" ca. 5 Minuten vor Ablauf des Zugriffstokens aufgerufen wird. Das reicht aus, um das Zugriffstoken zu extrahieren und zu aktualisieren, ohne die Seite zu aktualisieren.

Was nicht ganz funktioniert, wenn Computer aus dem Schlaf zurückkommt. Dies kann relativ einfach gelöst werden durch reloading the page on wake up.

+0

Ich habe dieses Reload beim Aufwecken verwendet und es hat gut funktioniert. Allerdings habe ich einen Web-Arbeiter wie in der Antwort weiter unten auf der gleichen Seite: https://stackoverflow.com/a/25100973/1161948 – ThisClark

1

Sie können dies mit listeners erreichen.

var auth2 = gapi.auth2.getAuthInstance(); 

// Listen for changes to current user. 
// (called shortly before expiration) 
auth2.currentUser.listen(function(user){ 

    // use new user in your OpenID Connect flow 

}); 

Damit können Sie die aktuellen Anmeldeinformationen behalten, solange der Browser aktiv bleibt.

Wenn der Computer in den Ruhezustand versetzt wird, muss zusätzliche Arbeit geleistet werden, um aktuelle Anmeldeinformationen zu erhalten.

if (auth2.isSignedIn.get() == true) { 
    auth2.signIn(); 
} 
+0

'auth2.signin()' wurde von einem Popup-Blocker blockiert, aber ich * war * kann mit Ihrer Technik einige nützliche Dinge tun, wie den Wert von 'user.getAuthResponse(). id_token' holen und in einer Variablen speichern, die ich für Autorisierungsheader verwende. Danke für das Teilen. – ThisClark

9

Wenn das Token abgelaufen ist, können Sie gapi.auth2.getAuthInstance().currentUser.get().reloadAuthResponse() anrufen. Es gibt ein Versprechen zurück.

+0

Das funktioniert für mich. Ich habe ein [RFE geöffnet, um dies der unterstützten API hinzuzufügen] (https://github.com/google/google-api-javascript-client/issues/234). – rhashimoto

+0

Hi @Jacek, wenn ich 'gapi.auth2.getAuthInstance(). CurrentUser.get() .reloadAuthResponse(). Then (fnsuccess() {}, fnerr() {})' verwende, wird der Fehler 'Uncaught TypeError: Eigenschaft 'postMessage' von null kann nicht gelesen werden. Kannst du helfen, etwas Code zu posieren? – Ravi

+1

'reloadAuthResponse()' ist jetzt Teil der dokumentierten API. – rhashimoto