J'ai joué avec l'API Google Analytics (V3) et j'ai rencontré des erreurs. Tout d'abord, tout est configuré correctement et fonctionne avec mon compte de test. Mais lorsque je veux récupérer des données d'un autre identifiant de profil (même compte Google Accont / GA), j'obtiens une erreur 403. La chose étrange est que les données de certains comptes GA renverront des données tandis que d'autres génèrent cette erreur.
J'ai révoqué le jeton et me suis authentifié une fois de plus, et il semble maintenant que je puisse récupérer les données de tous mes comptes. Problème résolu? Ne pas. Comme la clé d'accès expirera, je rencontrerai à nouveau le même problème.
Si j'ai bien compris les choses, on pourrait utiliser le resfreshToken pour obtenir un nouveau authenticationTooken.
Le problème est que lorsque je cours:
$client->refreshToken(refresh_token_key)
l'erreur suivante est renvoyée:
Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'
J'ai vérifié le code derrière la méthode refreshToken et suivi la demande dans le fichier «apiOAuth2.php». Tous les paramètres sont envoyés correctement. Le grant_type est codé en dur sur 'refresh_token' dans la méthode, il m'est donc difficile de comprendre ce qui ne va pas. Le tableau de paramètres ressemble à ceci:
Array ( [client_id] => *******-uqgau8uo1l96bd09eurdub26c9ftr2io.apps.googleusercontent.com [client_secret] => ******** [refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY [grant_type] => refresh_token )
La procédure est la suivante.
$client = new apiClient();
$client->setClientId($config['oauth2_client_id']);
$client->setClientSecret($config['oauth2_client_secret']);
$client->setRedirectUri($config['oauth2_redirect_uri']);
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');
$client->setState('offline');
$client->setAccessToken($config['token']); // The access JSON object.
$client->refreshToken($config['refreshToken']); // Will return error here
Est-ce un bug, ou ai-je complètement mal compris quelque chose?
Réponses:
Alors j'ai finalement compris comment faire ça. L'idée de base est que vous disposez du jeton que vous obtenez la première fois que vous demandez l'authentification. Ce premier jeton a un jeton d'actualisation. Le premier jeton d'origine expire après une heure. Après une heure, vous devez utiliser le jeton d'actualisation du premier jeton pour obtenir un nouveau jeton utilisable. Vous utilisez
$client->refreshToken($refreshToken)
pour récupérer un nouveau jeton. J'appellerai ce «jeton temporaire». Vous devez également stocker ce jeton temporaire car après une heure, il expire également et notez qu'il n'est pas associé à un jeton d'actualisation. Afin d'obtenir un nouveau jeton temporaire, vous devez utiliser la méthode que vous avez utilisée auparavant et utiliser le jeton d'actualisation du premier jeton. J'ai joint le code ci-dessous, ce qui est moche, mais je suis nouveau dans ce domaine ...la source
$client->isAccessTokenExpired()
cela ne vérifiera toujours que les heures tenues localement pour voir s'il pense que le jeton a expiré. Le jeton a peut-être encore expiré et l'application locale ne saura vraiment que lorsqu'elle essaiera de l'utiliser. Dans ce cas, le client API renverra une exception et n'actualisera pas automatiquement le jeton.Le problème est dans le jeton d'actualisation:
Quand une chaîne avec un
'/'
obtientjson encoded
, elle est échappée avec un'\'
, vous devez donc la supprimer.Le jeton d'actualisation dans votre cas doit être:
Ce que je suppose que vous avez fait, c'est que vous avez imprimé la chaîne json que Google a renvoyée et copié et collé le jeton dans votre code, car si vous
json_decode
le faites, il supprimera correctement le'\'
pour vous!la source
voici l'extrait de code pour définir le jeton, avant cela, assurez-vous que le type d'accès doit être défini sur hors ligne
Pour actualiser le jeton
cela actualisera votre token, vous devez le mettre à jour en session pour que vous puissiez le faire
la source
Le type d'accès doit être défini sur
offline
.state
est une variable que vous définissez pour votre propre usage, pas pour l'utilisation de l'API.Assurez-vous que vous disposez de la dernière version de la bibliothèque cliente et ajoutez:
Voir Formation de l'URL pour une explication des paramètres.
la source
$client
($client = new apiClient();
) pour utiliser le jeton d'actualisation?$client->setApprovalPrompt('force')
ainsi que$client->setAccessType('offline')
pour obtenir un nouveau jeton d'actualisation lors de l'autorisation. Sans forcer l'utilisateur à approuver l'étendue de l'accès, Google suppose que vous allez continuer à utiliser l'ancien jeton d'actualisation.La réponse postée par @ uri-weg a fonctionné pour moi mais comme je n'ai pas trouvé ses explications très claires, permettez-moi de la reformuler un peu.
Lors de la première séquence d'autorisation d'accès, dans le rappel, lorsque vous arrivez au point où vous recevez un code d'authentification, vous devez également enregistrer le jeton d'accès et le jeton d'actualisation .
La raison en est que google api vous envoie un jeton d'accès avec un jeton d'actualisation uniquement lorsque vous vous demandez une autorisation d'accès. Les jetons d'accès suivants seront envoyés sans jeton d'actualisation (sauf si vous utilisez l'
approval_prompt=force
option).Le jeton d'actualisation que vous avez reçu la première fois reste valide jusqu'à ce que l'utilisateur révoque l'autorisation d'accès.
En php simpliste, un exemple de séquence de rappel serait:
Et plus tard, en php simpliste, la séquence de connexion serait:
la source
// setAccessToken() expects json
c'était suffisant. Ou est-ce pour une autre partie du code?Voici le code que j'utilise dans mon projet et il fonctionne bien:
la source
Eu le même problème; mon script qui a fonctionné hier, pour une raison étrange n'a pas fonctionné aujourd'hui. Aucun changement.
Apparemment, c'était parce que mon horloge système était désactivée de 2,5 (!!) secondes, la synchronisation avec NTP l'a corrigé.
Voir aussi: https://code.google.com/p/google-api-php-client/wiki/OAuth2#Solving_invalid_grant_errors
la source
sudo apt-get install ntp
sur ma machine Debian pour installer NTP. Il a synchronisé l'horloge et le problème a été résolu.FYI: L'API Google Analytics 3.0 actualisera automatiquement le jeton d'accès si vous disposez d'un jeton d'actualisation lorsqu'il expire afin que votre script n'en ait jamais besoin
refreshToken
.(Voir la
Sign
fonction dansauth/apiOAuth2.php
)la source
Parfois, le jeton d'actualisation n'est pas généré en utilisant
$client->setAccessType ("offline");
.Essaye ça:
la source
J'ai utilisé l'exemple par smartcodes avec la version actuelle de l'API Google, mais celle-ci n'a pas fonctionné. Je pense que son API est trop obsolète.
Donc, je viens d'écrire ma propre version, basée sur l'un des exemples d'API ... Elle génère le jeton d'accès, le jeton de demande, le type de jeton, le jeton d'identification, l'heure d'expiration et l'heure de création sous forme de chaînes
Si vos informations d'identification client et votre clé de développeur sont correctes, ce code devrait fonctionner immédiatement.
la source
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
. Pourquoi vous redirigez vers la même page? est-ce nécessaire?J'ai le même problème avec google / google-api-php-client v2.0.0-RC7 et après une recherche de 1 heures, j'ai résolu ce problème en utilisant json_encode comme ceci:
la source
Cela fonctionne très bien ici, peut-être que cela pourrait aider n'importe qui:
index.php
oauth2callback.php
client.php
action.php
la source
Google a apporté quelques modifications depuis la publication de cette question.
Voici mon exemple de travail actuellement.
la source
J'utilise google-api-php-client v2.2.2 Je reçois un nouveau jeton avec un
fetchAccessTokenWithRefreshToken();
appel de fonction if sans paramètres, il renvoie un jeton d'accès mis à jour et le jeton actualisé n'est pas perdu.la source
Vous devez enregistrer le jeton d'accès dans un fichier ou une base de données en tant que chaîne json lors de la demande d'autorisation initiale et définir le type d'accès sur hors ligne
$client->setAccessType("offline")
Ensuite, lors des requêtes API suivantes, récupérez le jeton d'accès de votre fichier ou de votre base de données et transmettez-le au client:
Vous devez maintenant vérifier si le jeton a expiré:
La
fetchAccessTokenWithRefreshToken()
fonction fera le travail pour vous et fournira un nouveau jeton d'accès, le sauvegardera dans votre fichier ou votre base de données.la source
Selon l' authentification sur Google: OAuth2 continue de renvoyer «invalid_grant»
"Vous devez réutiliser le jeton d'accès que vous avez obtenu après la première authentification réussie. Vous obtiendrez une erreur invalid_grant si votre jeton précédent n'a pas encore expiré. Mettez-le en cache quelque part afin de pouvoir le réutiliser."
J'espère que ça aide
la source
utilisez l'extrait de code suivant pour obtenir votre jeton d'actualisation
la source