2015-09-21 15 views
13

Come autorizzare un cliente di Google in modo permanente fino a quando l'utente revoca l'autorizzazione?Accesso offline PHP API di Google, "invalid_grant: codice già utilizzato"

Sto tentando di creare un'app che si connette a Google Calendar. Deve funzionare in PHP e quindi sto usando il client PHP API di Google fornito da google.

L'app deve avere accesso offline in modo che funzioni quando l'utente non è nella sessione. L'app ha lo scopo di consentire all'utente di gestire e visualizzare i suoi calendari pubblicamente su siti Web e simili.

Ho creato credenziali in Google Console, utilizzando il metodo di servizio (con un ID client e un segreto client). Utilizzando il client API di Google ho anche richiesto l'autorizzazione dell'utente. Apro una nuova finestra del browser, l'utente autorizza, un codice di autorizzazione viene restituito da Google. Prendo questo codice, lo memorizzo e lo uso per autorizzare il client, che si collega con successo a Google Calendar e scambia dati.

Ora ho capito che questo è un token che sta per scadere. A meno che non si utilizzi l'accesso offline, che ho impostato. Tuttavia, dopo un paio di minuti o meno sarò sempre ottengo un errore: Error fetching OAuth2 access token, message: 'invalid_grant: Code was already redeemed.

Questo è il codice che uso per il collegamento del client:

$client = new \Google_Client(); 
$client->setApplicationName('My App'); 
$client->setScopes(array(\Google_Service_Calendar::CALENDAR)); 
$client->setClientId($this->google_client_id); 
$client->setClientSecret($this->google_client_secret); 
$client->setRedirectUri($this->google_client_redirect); 
$client->setAccessType('offline'); 

if ($code = $this->google_client_auth) { 

    try { 

     $client->authenticate($code); 

    } catch(\Exception $e) { 
      var_dump($e); 
    }  

} 

return new \Google_Service_Calendar($client); 

Questo è un metodo all'interno di una classe.

L'ID client e il segreto del client sono memorizzati nelle impostazioni dell'app.

Sto anche memorizzando il codice restituito dall'utente in un'impostazione, ma penso che questo sia dove sto facendo male? Sto mettendo il link a una finestra di Google OAuth in un metodo separato (che usa anche lo stesso ID client e segreto e imposta anche il metodo offline. E ottenere l'autorizzazione funziona. Posso accedere ai calendari. Non dura solo a lungo ...

risposta

24

Esistono tre tipi di codici o i rendimenti dei server gettoni Googles Authentcation.

  1. codice di autenticazione
  2. token di accesso
  3. Token di aggiornamento.

codice di autenticazione

Quando un utente fa clic sul form Authentcation e concede l'accesso dell'applicazione. Google ti restituisce un codice Authentcation. Dovresti prendere questo codice e cambiarlo per un token di accesso e un token di aggiornamento. Questo codice viene utilizzato solo una volta se si tenta di utilizzarlo di nuovo si otterrà un messaggio di errore.

invalid_grant: Code was already redeemed.

token di accesso

token di accesso vengono utilizzati per accedere alle API questo token deve essere inviato insieme con ogni richiesta che fate.token di accesso sono di breve durata che lavorano per un'ora e poi smettono di lavorare

token di aggiornamento

gettoni Refresh dovrebbe essere salvato sul server da qualche parte. Una volta scaduto il token di accesso, è possibile utilizzare il token di aggiornamento per ottenere un nuovo token di accesso.

Il tuo problema è che stai salvando il codice di autenticazione che non ti è di alcuna utilità. Devi trovare il token di aggiornamento e salvarlo.

+0

grazie ... ma perché ho bisogno sia del token di accesso che del token di aggiornamento immediatamente? L'API ha due metodi getAccessToken e getRefreshToken. Ma solo un setter setAccessToken. Quando ottengo il codice di autenticazione da parte dell'utente posso eseguire getAuth() -> autenticare ma l'API non dice se quello che restituisce è un token di accesso o di aggiornamento. Devo passare il risultato di getAuth-> authenticate a setAccessToken? A cosa serve getAccessToken, quindi? – unfulvio

+1

inoltre, dall'API PHP di Google sembra che il token di accesso sia un oggetto JSON, ma il token di aggiornamento è una stringa? Quindi devo passare il token di aggiornamento al metodo getAuth-> authenticate()? – unfulvio

+1

ha trovato alcune risposte qui: https://developers.google.com/identity/protocols/OAuth2WebServer?hl=it – unfulvio

Problemi correlati