He estado jugando con la API de Google Analytics (V3) y me he encontrado con algunos errores. En primer lugar, todo está configurado correctamente y funcionó con mi cuenta de prueba. Pero cuando quiero obtener datos de otra ID de perfil (Misma cuenta de Google / Cuenta GA), obtengo un error 403. Lo extraño es que los datos de algunas cuentas de GA devolverán datos mientras que otras generan este error.
Revoqué el token y me autentiqué una vez más, y ahora parece que puedo obtener datos de todas mis cuentas. ¿Problema resuelto? No. Como la clave de acceso caducará, volveré a tener el mismo problema.
Si he entendido bien las cosas, se podría usar resfreshToken para obtener un nuevo authenticationTooken.
El problema es, cuando ejecuto:
$client->refreshToken(refresh_token_key)
se devuelve el siguiente error:
Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'
Revisé el código detrás del método refreshToken y rastreé la solicitud hasta el archivo "apiOAuth2.php". Todos los parámetros se envían correctamente. Grant_type está codificado en 'refresh_token' dentro del método, por lo que es difícil para mí entender qué está mal. La matriz de parámetros se ve así:
Array ( [client_id] => *******-uqgau8uo1l96bd09eurdub26c9ftr2io.apps.googleusercontent.com [client_secret] => ******** [refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY [grant_type] => refresh_token )
El procedimiento es el siguiente.
$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
¿Es esto un error o he entendido mal algo por completo?
fuente
Respuestas:
Así que finalmente descubrí cómo hacer esto. La idea básica es que tenga el token que obtiene la primera vez que solicita la autenticación. Este primer token tiene un token de actualización. El primer token original caduca después de una hora. Después de una hora, debe usar el token de actualización del primer token para obtener un nuevo token utilizable. Usas
$client->refreshToken($refreshToken)
para recuperar un nuevo token. A esto lo llamaré "ficha temporal". También debe almacenar este token temporal porque después de una hora también caduca y tenga en cuenta que no tiene un token de actualización asociado. Para obtener un nuevo token temporal, debe usar el método que usó antes y usar el primer token de actualización. He adjuntado el código a continuación, que es feo, pero soy nuevo en esto ...fuente
$client->isAccessTokenExpired()
solo comprobará los tiempos que se mantienen localmente para ver si cree que el token ha expirado. Es posible que el token aún haya caducado y la aplicación local solo lo sabrá realmente cuando intente usarlo. En este caso, el cliente API devolverá una excepción y no actualizará automáticamente el token.El problema está en el token de actualización:
Cuando una cadena con un
'/'
getjson encoded
, se escapa con un'\'
, por lo tanto, debe eliminarlo.El token de actualización en su caso debería ser:
Lo que supongo que ha hecho es que imprimió la cadena json que Google envió y copió y pegó el token en su código porque si lo
json_decode
hace, ¡lo eliminará correctamente'\'
!fuente
aquí está el fragmento para configurar el token, antes de eso, asegúrese de que el tipo de acceso debe establecerse como sin conexión
Para actualizar el token
esto actualizará su token, debe actualizarlo en la sesión para que pueda hacerlo
fuente
El tipo de acceso debe establecerse en
offline
.state
es una variable que configura para su propio uso, no para el uso de la API.Asegúrese de tener la última versión de la biblioteca cliente y agregue:
Consulte Formación de la URL para obtener una explicación de los parámetros.
fuente
$client
($client = new apiClient();
) para usar el token de actualización?$client->setApprovalPrompt('force')
y$client->setAccessType('offline')
obtener un nuevo token de actualización durante la autorización. Sin obligar al usuario a aprobar el alcance del acceso, Google asume que seguirá usando el token de actualización anterior.La respuesta publicada por @ uri-weg funcionó para mí, pero como no encontré sus explicaciones muy claras, permítanme reformularlas un poco.
Durante la secuencia del primer permiso de acceso, en la devolución de llamada, cuando llega al punto en el que recibe un código de autenticación, debe guardar el token de acceso y el token de actualización. también.
El motivo es que la API de Google le envía un token de acceso con un token de actualización solo cuando se le solicita permiso de acceso. Los siguientes tokens de acceso se enviarán sin ningún token de actualización (a menos que use el
approval_prompt=force
opción).El token de actualización que recibió la primera vez permanece válido hasta que el usuario revoca el permiso de acceso.
En php simplista, un ejemplo de la secuencia de devolución de llamada sería:
Y más adelante, en php simplista, la secuencia de conexión sería:
fuente
// setAccessToken() expects json
era suficiente. ¿O es para otra parte del código?Aquí está el código que estoy usando en mi proyecto y está funcionando bien:
fuente
Tuvo el mismo problema; mi guión que funcionó ayer, por alguna extraña razón no lo hizo hoy. Sin cambios.
Aparentemente, esto se debió a que el reloj de mi sistema estaba apagado en 2.5 (!!) segundos, la sincronización con NTP lo solucionó.
Consulte también: https://code.google.com/p/google-api-php-client/wiki/OAuth2#Solving_invalid_grant_errors
fuente
sudo apt-get install ntp
en mi máquina Debian para instalar NTP. Sincronizó el reloj y se solucionó el problema.Para su información: la API de Google Analytics 3.0 actualizará automáticamente el token de acceso si tiene un token de actualización cuando caduque, por lo que su secuencia de comandos nunca necesita
refreshToken
.(Ver la
Sign
función enauth/apiOAuth2.php
)fuente
A veces, el Token de actualización no se genera al usar
$client->setAccessType ("offline");
.Prueba esto:
fuente
Usé el ejemplo de códigos inteligentes con la versión actual de la API de Google, pero ese no funcionó. Creo que su API está demasiado desactualizada.
Entonces, acabo de escribir mi propia versión, basada en uno de los ejemplos de API ... Genera token de acceso, token de solicitud, tipo de token, token de identificación, tiempo de vencimiento y tiempo de creación como cadenas
Si sus credenciales de cliente y clave de desarrollador son correctas, este código debería funcionar de inmediato.
fuente
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
. ¿Por qué redirige a la misma página? ¿Es esto necesario?Tengo el mismo problema con google / google-api-php-client v2.0.0-RC7 y después de buscar durante 1 hora, resolví este problema usando json_encode así:
fuente
Esto aquí funciona muy bien, tal vez podría ayudar a cualquiera:
index.php
oauth2callback.php
client.php
action.php
fuente
Google ha realizado algunos cambios desde que se publicó originalmente esta pregunta.
Aquí está mi ejemplo de trabajo actual.
fuente
Utilizo google-api-php-client v2.2.2 Obtengo un nuevo token con la
fetchAccessTokenWithRefreshToken();
llamada a la función sin parámetros, devuelve un token de acceso actualizado y el token actualizado no se pierde.fuente
Debe guardar el token de acceso en el archivo o la base de datos como una cadena json durante la solicitud de autorización inicial y establecer el tipo de acceso en fuera de línea
$client->setAccessType("offline")
Luego, durante las solicitudes de API posteriores, tome el token de acceso de su archivo o base de datos y páselo al cliente:
Ahora debe verificar si el token ha expirado:
La
fetchAccessTokenWithRefreshToken()
función hará el trabajo por usted y le proporcionará un nuevo token de acceso, lo guardará de nuevo en su archivo o base de datos.fuente
Según Authentication en google: OAuth2 sigue devolviendo 'invalid_grant'
"Debe reutilizar el token de acceso que obtiene después de la primera autenticación exitosa. Obtendrá un error de invalid_grant si su token anterior aún no ha caducado. Guárdelo en algún lugar para poder reutilizarlo".
Espero eso ayude
fuente
use el siguiente fragmento de código para obtener su token de actualización
fuente