web-dev-qa-db-fra.com

API Google PHP accès hors ligne, "invalid_grant: le code a déjà été utilisé"

Comment autoriser un client Google de façon permanente jusqu'à ce que l'utilisateur révoque l'autorisation?

J'essaie de créer une application qui se connecte à Google Agenda. Il doit fonctionner dans PHP et donc j'utilise l'API Google PHP client fourni par google.

L'application doit avoir un accès hors ligne pour qu'elle fonctionne lorsque l'utilisateur n'est pas dans la session. L'application est destinée à permettre à l'utilisateur de gérer et d'afficher ses calendriers publiquement sur des sites Web et autres.

J'ai créé des informations d'identification dans la console Google, en utilisant la méthode de service (avec un ID client et un secret client). En utilisant le client Google API, j'ai également demandé l'autorisation à l'utilisateur. J'ouvre une nouvelle fenêtre de navigateur, l'utilisateur autorise, un code d'autorisation est retourné par Google. Je prends ce code, le stocke et l'utilise pour autoriser le client, qui se connecte avec succès à Google Calendar et échange des données.

Maintenant, j'ai compris que c'est un jeton qui va expirer. Sauf si l'on utilise un accès hors ligne, que j'ai défini. Cependant, après quelques minutes ou moins, j'obtiendrai toujours une erreur: Error fetching OAuth2 access token, message: 'invalid_grant: Code was already redeemed.

Voici le code que j'utilise pour connecter le 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 );

Il s'agit d'une méthode à l'intérieur d'une classe.

L'ID client et le secret client sont stockés dans les paramètres de l'application.

Je stocke également le code renvoyé par l'utilisateur dans un paramètre, mais je pense que c'est là que je me trompe? Je mets le lien vers une fenêtre Google OAuth dans une fenêtre distincte) (qui utilise également le même identifiant client et le même secret et définit également la méthode hors ligne). Et pour obtenir l'autorisation, cela fonctionne. Je peux accéder aux calendriers. Cela ne dure tout simplement pas longtemps ...

16
unfulvio

Il existe trois types de codes ou de jetons renvoyés par le serveur Googles Authentcation.

  1. Code d'identification
  2. Jeton d'accès
  3. Actualisez le jeton.

Code d'authentification

Lorsqu'un utilisateur clique sur le formulaire d'authentification et accorde l'accès à votre application. Google vous renvoie un code d'authentification. Vous devez prendre ce code et l'échanger contre un jeton d'accès et un jeton d'actualisation. Ce code n'est utilisé qu'une seule fois si vous essayez de le réutiliser, vous obtiendrez un message d'erreur.

invalid_grant: le code a déjà été utilisé.

jeton d'accès

Les jetons d'accès sont utilisés pour accéder aux API. Ce jeton doit être envoyé avec chaque demande que vous faites. Les jetons d'accès sont de courte durée, ils travaillent pendant une heure, puis ils cessent de fonctionner

Actualiser le jeton

Les jetons d'actualisation doivent être enregistrés sur votre serveur quelque part. Une fois le jeton d'accès expiré, vous pouvez utiliser le jeton d'actualisation pour obtenir un nouveau jeton d'accès.

Votre problème est que vous enregistrez le code d'authentification qui ne vous est d'aucune utilité. Vous devez trouver le jeton d'actualisation et l'enregistrer.

28
DaImTo