2015-08-21 16 views
17

Sto utilizzando Google Sign-In. Un utente arriva al mio sito e accede con gapi.auth2.getAuthInstance().signIn(), oppure sono già connessi e quando la pagina viene caricata (o ricaricata) recuperiamo lo stato. A questo punto ho un token di identità valido per un'ora che posso convalidare sul server.Come aggiornare gli accessi di accesso google scaduti?

Quando un utente lascia il browser seduto (ad esempio, durante la notte), questo token scade. gapi.auth2.getAuthInstance().isSignedIn.get() restituisce true, ma il token non convalida.

Come posso accedere a un utente e mantenerlo connesso mentre la loro sessione è attiva (ovvero il browser non è stato chiuso)? O aggiorna il token? Qualcosa di più grazioso di ricaricare la pagina ...

Modifica: il token di aggiornamento non è una risposta corretta; Non voglio l'accesso offline (e non voglio chiedere il permesso). Google ovviamente pensa che l'utente sia ancora registrato nella mia applicazione; l'utente può ricaricare la pagina e ottenere un nuovo token senza fornire nuovamente le credenziali. Sicuramente esiste un meccanismo più elegante di un iframe nascosto per ottenere un token aggiornato?

+1

Sei riuscito a trovare una risposta corretta a questo? Ho lo stesso problema e sono in perdita su come risolverlo. Inizialmente sono andato anche per i Token di aggiornamento, come suggerito nella risposta, ma sono d'accordo sul fatto che questa non è una soluzione reale. – csvan

+0

Nessuna risposta ancora, che è sconcertante. Quando avrò un po 'di tempo libero cercherò di avviare una seconda sessione di login in un iframe nascosto e raccogliere un nuovo token da lì.Nel frattempo i miei utenti sono costretti a ricaricare la loro pagina una volta all'ora - schifo. – stickfigure

+1

L'API di Google tenta di aggiornare il suo token di accesso 5 minuti prima che scada, quindi la maggior parte delle sessioni attive non dovrebbe essere un problema. Il vero problema è cosa succede con ['setTimeout()' quando il computer dorme] (http://stackoverflow.com/a/6347336/1462337). Su alcune piattaforme (tutte?) L'aggiornamento del token sarà ulteriormente ritardato dal momento in cui il computer è in stop, il che probabilmente sarà il tempo trascorso della scadenza del token corrente. La soluzione suggerita da @ JacekKopecký - testare per la scadenza e usare 'reloadAuthResponse()' - funziona bene. L'unico inconveniente è che questo è un metodo non documentato. – rhashimoto

risposta

0

È possibile utilizzare Token di aggiornamento per ottenere l'accesso offline. Come per il riferimento ufficiale

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.

In pratica si otterrà il refresh token la prima volta che si chiede per l'autenticazione. È necessario salvare quel token in modo sicuro per un uso futuro. Lo access token (indicato come token di identità) scade dopo un'ora. Successivamente, è necessario utilizzare refresh token ogni volta che si desidera ottenere un nuovo access token utilizzabile.

A seconda della libreria client che si sta utilizzando, la sintassi sarà diversa. di seguito è riportato un esempio per la libreria client php.

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

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

controllo this per i dettagli passi.

+0

Questa risposta manca qualcosa di essenziale. L'utente può ricaricare la pagina e ottenere un nuovo token senza reinserire le proprie credenziali. In effetti, posso quasi certamente usare questo comportamento con un iframe nascosto per ottenere un nuovo token. Pertanto, Google ritiene che l'utente sia ancora "connesso" al mio sito in modo significativo e non mi richiede di chiedere l'accesso offline. Non voglio l'accesso offline e non voglio chiedere questo permesso. Voglio solo che la loro sessione del browser continui allo stesso modo di una sessione di login di Facebook. – stickfigure

+0

Per quanto ne so, la sessione del browser per l'autenticazione continuerà. come dici tu ottieni da auth2 'gapi.auth2.getAuthInstance(). isSignedIn.get()'. Ma non è possibile eseguire richieste API estese senza 'token di accesso'. Quindi è necessario il 'refresh token' per ottenere' token di accesso 'in seguito. – arifin4web

+0

Non sembra strano? La loro API dice "hai effettuato l'accesso" e tuttavia il token restituisce, con lo scopo esplicito di consentire al mio server di convalidare l'autenticità di una chiamata, non è valido? Sono chiaramente iscritto o non lo sono: le API di Google lo capiscono e ricaricare la pagina stabilisce chiaramente questo fatto in un modo o nell'altro ogni volta. Questo sembra un bug, tranne che è così ovvio che è difficile vedere come potrebbe essere permesso di esistere. – stickfigure

2

FWIW, siamo riusciti a (principalmente) farlo funzionare tramite listener approach. Sembra che il callback "userChanged" sia invocato ~ 5 minuti prima della scadenza del token di accesso. Questo è sufficiente per noi per estrarre e aggiornare il token di accesso senza aggiornare la pagina.

Ciò che non funziona è quando il computer ritorna dal sonno. Questo può essere risolto in modo relativamente semplice da reloading the page on wake up.

+0

Ho usato questa ricarica sull'approccio wakeup e ha funzionato bene. Tuttavia, ho utilizzato un web worker come nella risposta più avanti nella stessa pagina: https://stackoverflow.com/a/25100973/1161948 – ThisClark

1

È possibile eseguire questa operazione con listeners.

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 

}); 

Ciò consentirà di mantenere le credenziali correnti, a condizione che il browser rimanga attivo.

Se il computer viene messo a riposo, è necessario eseguire ulteriori operazioni per ottenere le credenziali correnti.

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

'auth2.signin()' è stato bloccato da un blocco popup, ma I * was * in grado di fare alcune cose utili con la tua tecnica, come recuperare il valore da 'user.getAuthResponse(). id_token' e memorizzarlo in una variabile che utilizzo per le intestazioni di autorizzazione. Grazie per aver condiviso questo. – ThisClark

9

Se il token è scaduto, è possibile chiamare gapi.auth2.getAuthInstance().currentUser.get().reloadAuthResponse(). Restituisce una promessa.

+0

Questo funziona per me. Ho aperto un [RFE per aggiungerlo all'API supportata] (https://github.com/google/google-api-javascript-client/issues/234). – rhashimoto

+0

Ciao @Jacek, se uso 'gapi.auth2.getAuthInstance(). CurrentUser.get(). ReloadAuthResponse(). Then (fnsuccess() {}, fnerr() {})', genera errore 'Uncaught TypeError: Impossibile leggere la proprietà "postMessage" di null'. Puoi aiutarmi a proporre un codice? – Ravi

+1

'reloadAuthResponse()' è ora parte dell'API documentata. – rhashimoto

Problemi correlati